sheng00 的所有文章

使用angularjs directive生成api方法供其他地方调用angularjs directive expose api

有些时候我们需要directive生成api,可以在其他地方(controller)调用
image1419911269
下面介绍下简单的步骤:

使用directive的双向绑定绑定controller里的变量

html:
<div expose="exposedApi"></div>
js:

directive('expose',function(){
  return {
    restrict: "A",
    scope: {
      api: "=expose"
    }
  };

这个时候controller离的exposedApi变量和directive里的api是双向绑定的

给directive里的api增加可调用的方法

directive('expose',function(){
  return {
    restrict: "A",
    scope: {
      api: "=expose"
    },
    controller: function($scope){
      $scope.number = 0;
      $scope.api={
        count:function(){
          $scope.number ++;
        }
      };
    },
    template: '<div class="well">' +
              '<p>count: {{number}}</p>' +
              '</div>'
  };

调用directive里的方法

controller("ctrl",function($scope){
  $scope.count = function(){
    $scope.exposedApi.count();
  };
})

Demo:

http://shengoo.github.io/angularjs-practice

完整代码:

<!DOCTYPE html>
<html ng-app="app">
<head lang="en">
  <meta charset="UTF-8">
  <title></title>
  <link rel="stylesheet" href="../bower_components/bootstrap/dist/css/bootstrap.css" />
  <script src="../bower_components/angular/angular.js"></script>
</head>
<body ng-controller="ctrl">
<div class="container">
<div expose="exposedApi"></div>
<a ng-click="count()" class="btn btn-primary">click</a>
<div expose="exposedApi2"></div>
<a ng-click="count2()" class="btn btn-primary">click</a>
</div>
<script>
angular.module("app",[])
.controller("ctrl",function($scope){
  $scope.count = function(){
    $scope.exposedApi.count();
  };
  $scope.count2 = function(){
    $scope.exposedApi2.count();
  };
})
.directive('expose',function(){
  return {
    restrict: "A",
    scope: {
      api: "=expose"
    },
    controller: function($scope){
      $scope.number = 0;
      $scope.api={
        count:function(){
          $scope.number ++;
        }
      };
    },
    template: '<div class="well">' +
              '<p>count: {{number}}</p>' +
              '</div>'
  };
})
</script>
</body>
</html>

angularjs directive

在AngularJS中,Dom操作应该在directive里进行,而不应该在controllers, services或者其他任何地方。

directives命名

  • 使用不重复的前缀
    • 防止和其他人重复
    • 易读
  • 不要用ng-作为你的directive的前缀
  • 常见情况:两个单词
    • AngularUI project 用的是 “ui-“

什么时候用directives?

  • 可复用的HTML控件
    <my-widget>

  • 可复用的HTML行为
    <div ng-click="...">

  • 包装一个jQuery插件
    <div ui-date></div>

  • 你需要和DOM交互的绝大多数情况

创建一个directive

先给你的directive创建一个module

angular.module('MyDirectives',[]);

在你的app里加入directive module的依赖

angular.module('app',['MyDirectives']);

注册你的directive

angular.module('MyDirectives')
.directive('myDirective', function(){
  // TODO:
});

在HTML里使用你的directive

<div my-directive>...</div>

Restrict参数

‘A’

attributes
<div my-directive></div>

‘E’

element
<my-directive></my-directive

‘C’ ‘M’

rarely used
‘C’: classes ‘M’ : comments

组合

restrict: 'AE'

隔离的scope

directive默认是没有scope的,我们可以给它一个scope

scope: {
  someParam: '='
}

或者
scope: true
这个scope不会继承其他scope

scope参数

scope参数是从HTML的属性(attribute)传进来的

scope: {
  param1: '=', // 双向绑定(directive和controller)
  param2: '@', // 单向绑定
  param3: '&'  // 单向行为
}
<div my-directive
  param1="someVariable"
  param2="My name is {{name}}"
  param3="doSth()"
>

$digest already in progress 解决办法

常见原因

除了简单的不正确调用 $apply$digest,有些情况下,即使没有犯错,也有可能得到这个错误。

可能出错的代码

function MyController($scope, thirdPartyComponent) {
  thirdPartyComponent.getData(function(someData) {
    $scope.$apply(function() {
      $scope.someData = someData;
    });
  });
}

改成这样就可以了

function MyController($scope, thirdPartyComponent) {
  thirdPartyComponent.getData(function(someData) {
    $timeout(function() {
      $scope.someData = someData;
    }, 0);
  });
}

使用git在多台机器上同步sublime text的设置和插件

package文件夹位置

windows: C:\Users\[YourName]\AppData\Roaming\Sublime Text 3\Packages
mac: /Library/Application\ Support/Sublime\ Text\ 3/Packages/
linux:

有些文件/文件夹不需要同步,加入到.gitignore

Package Control.last-run
Package Control.ca-list
Package Control.ca-bundle
Package Control.system-ca-bundle
Package Control.cache/
Package Control.ca-certs/

在第一台电脑上

cd [package folder]/User/
git init
git add
git commit -m "Initial"
git remote add origin [your git repo]
git push origin master

这样就可以在其他电脑上clone这个repo了

cd [package folder]
mv User User.old
git clone [your git repo] User

如果设置有了改变,再同步到repo里

cd [package folder]/User
git add -A
git commit -m "Update settings"
git push

在其他电脑上同步

cd [package folder]/User
git pull

"git add -A" 和 "git add ." 的区别

git add -A” 相当于 “git add .; git add -u“.
git add .“虽然看起来像是把目录下所有文件都添加,但是其实并没有,它只会添加新建和更改过的文件。
git add -u” 中-u代表的是update,只会记录已有文件的update,不会记录新建的文件。
git add -A” 可以做上面两件事的.
你可以按照下面的命令去测试这些区别:

git init
echo Change me > change-me
echo Delete me > delete-me
git add change-me delete-me
git commit -m initial
echo OK >> change-me
rm delete-me
echo Add me > add-me
git status
# Changed but not updated:
#   modified:   change-me
#   deleted:    delete-me
# Untracked files:
#   add-me
git add .
git status
# Changes to be committed:
#   new file:   add-me
#   modified:   change-me
# Changed but not updated:
#   deleted:    delete-me
git reset
git add -u
git status
# Changes to be committed:
#   modified:   change-me
#   deleted:    delete-me
# Untracked files:
#   add-me
git reset
git add -A
git status
# Changes to be committed:
#   new file:   add-me
#   modified:   change-me
#   deleted:    delete-me

总结:

  • git add -A?添加所有
  • git add .?添加新文件和修改的文件,?不包括删除的
  • git add -u?添加修改和和删除的文件,?不包括新增的

使用AngularJS service作为KendoUI的datasource

angular.module("app", ["kendo.directives"])
.controller("news", function($scope,newsService) {
  var dataSource = new kendo.data.DataSource({
    transport: {
      read: dataSourceRead
    }
  });
  function dataSourceRead(options){
    //todo: show loading
    newsService.getByCategory($scope.selectedCategory.value)
      .then(
        function(response){
          options.success(response);
          //todo: hide loading
        },
        function(response){
          options.error(response);
          //todo: handle errors.
        });
  }
  $scope.newsListViewOptions = {
    dataSource: dataSource
  };
})
.service('newsService', function($q, $http) {
  this.getByCategory = function(category){
    var url = "your url";
    var request = $http({
      method: "jsonp",
      url: url
    });
    return( request.then( handleSuccess, handleError ) );
  };
  function handleError( response ) {
    //if no message return from server
    if (
      ! angular.isObject( response.data ) ||
      ! response.data.message
      ) {
      return( $q.reject( "An unknown error occurred." ) );
    }
    return( $q.reject( response.data.message ) );
  }
  function handleSuccess( response ) {
    return( response.data );
  }
});

Android service 自动重启

当Android的service被停止(内存不够、被其他app杀掉)的时候,加入以下代码到你的service里,就可以马上重新启动了。

@Override
public void onDestroy() {
  super.onDestroy();
  // Restart service in 500 ms
  ((AlarmManager) getSystemService(Context.ALARM_SERVICE))
  .set(AlarmManager.RTC,
    System.currentTimeMillis() + 500,
    PendingIntent.getService(this, 3, new Intent(this, TaskService.class), 0));
}

angularjs service factory provider 区别

Services
Syntax: module.service( ‘serviceName’, function );
Result: When declaring serviceName as an injectable argument you will be provided with an instance of the function. In other words new FunctionYouPassedToService().
Factories
Syntax: module.factory( ‘factoryName’, function );
Result: When declaring factoryName as an injectable argument you will be provided with the value that is returned by invoking the function reference passed to module.factory.
Providers
Syntax: module.provider( ‘providerName’, function );
Result: When declaring providerName as an injectable argument you will be provided with ProviderFunction().$get(). The constructor function is instantiated before the $get method is called – ProviderFunction is the function reference passed to module.provider.