角度指令范围不反映控制器范围的变化

时间:2015-10-17 08:38:15

标签: angularjs angularjs-directive angularjs-scope directive

我正在编写一个指令,需要在网格中显示搜索框和一些值。输入搜索文本可能会更改网格中的值。

http://jsfiddle.net/rtv2222/st55azbg/5/

<div ng-controller="MyCtrl">
  <my-directive values='some.values' onsearchtextchange='onsearchtextchange' searchtext='some.searchtext'></my-directive>
  </div>

  var demo = angular.module('demo', []);
  demo.directive('myDirective', function($parse) {
  return {
    restrict: "E",
    scope: {         
        values: '=',
        searchtext: '=',
        onsearchtextchange: '&'
    },
    template: '{{values.length}} <input ng-model="searchtext">',
    link:
    function(scope, element, attrs){
        scope.$watch('searchtext', function (tmpStr){
            setTimeout(function() {
                // if searchStr is still the same..
                // go ahead and retrieve the data
                if (tmpStr === scope.searchtext)
                {
                    scope.onsearchtextchange()(scope.searchtext);
                    console.log(scope.values.length);
                }
            }, 1000);
        });
    }
}
});

function MyCtrl ($scope) {
$scope.some = {};
$scope.some.values = [{a:1}, {a:2}];
$scope.some.searchtext = "";
$scope.onsearchtextchange = function(searchtext) {
    if (searchtext && searchtext.length != 0) {
        $scope.some.values = [{a:1}];
        console.log('values.length is:' + $scope.some.values.length);
    }
    else {
        $scope.some.values = [{a:1}, {a:2}];
        console.log('values.length is:' + $scope.some.values.length);
    }
}
};

我将searchtext,onsearchtextchange回调和带隔离范围的值绑定到指令。我观察searchtext并对控制器函数进行回调,该函数更新值列表。

然而,我发现指令范围并未反映&#39;值的变化。在控制器范围内。

如果回调更新控制器范围上的值,我应该怎么做才能更新子范围?

正如您在运行示例时所看到的,当更改searchtext时,将调用onsearchtextchange回调并更改控制器scope.some.values。但是,指令范围值仍然是旧值。

2 个答案:

答案 0 :(得分:0)

在我的控制器回调中添加$ scope。$ apply()可以解决问题。

答案 1 :(得分:0)

您可以使用AngularJS $timeout 服务,而不是使用setTimeout(),该服务在内部配有$scope.$apply()。这样,您无需在控制器中调用$scope.$apply()

demo.directive('myDirective', function($parse, $timeout) {
  return {
    restrict: "E",
    scope: {         
        values: '=',
        searchtext: '=',
        onsearchtextchange: '&'
    },
    template: '{{values.length}} <input ng-model="searchtext">',
    link:
    function(scope, element, attrs){
        scope.$watch('searchtext', function (tmpStr){
            $timeout(function() {
                // if searchStr is still the same..
                // go ahead and retrieve the data
                if (tmpStr === scope.searchtext)
                {
                    scope.onsearchtextchange()(scope.searchtext);
                    console.log(scope.values.length);
                }
            }, 1000);
        });
      }
   };
});