为什么在指令的链接功能中对$ scope进行的更改未在UI上反映出来?

时间:2016-06-17 08:54:09

标签: javascript angularjs angularjs-directive

AngularJS指令' link函数更改隔离范围数据未反映在UI中。

以下是一个例子:

var myApp = angular.module('myApp', []);

myApp.directive('myDirective', function () {
    return {
        restrict: 'A',
        template: '<span>Title: {{myParams.title}}</span>',
        scope: {
            myParams: '='
        },
        link: function ($scope) {
            // the new value is not reflected in ui
            $scope.myParams.title = 'this is myDirective';
        }
    };
});

HTML:

 <div my-directive my-params="{title: 'this is title'}"></div>

我希望HTML页面显示this is myDirective,但事实上它是this is title

另外,你能解释为什么它会这样显示。感谢

2 个答案:

答案 0 :(得分:5)

原因是my-params="{title: 'this is title'}"常量表达式而不是可分配的。因此,即使您尝试覆盖'title'属性,它也会从常量中被覆盖。检查this fiddle。它包含您的代码,并设置为与Angular 1.4一起使用。区别在于指令如上所述使用一次,而一次使用来自控制器的非恒定值:

<div ng-app="app" ng-controller="Ctrl as ctrl">
  <div my-directive my-params="{title: 'this is title'}"></div>
  <div my-directive my-params="data"></div>
</div>

第二个实例(非常量表达式)有效。

现在尝试将Angular版本更改为1.2。请注意,现在Angular会抛出无限的摘要错误:

VM1033 angular.js:9101 Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: [["fn: parentValueWatch; newVal: {\"title\":\"this is title\"}; oldVal: {\"title\":\"this is title\"}"],["fn: parentValueWatch; newVal: {\"title\":\"this is title\"}; oldVal: {\"title\":\"this is title\"}"],["fn: parentValueWatch; newVal: {\"title\":\"this is title\"}; oldVal: {\"title\":\"this is title\"}"],["fn: parentValueWatch; newVal: {\"title\":\"this is title\"}; oldVal: {\"title\":\"this is title\"}"],["fn: parentValueWatch; newVal: {\"title\":\"this is title\"}; oldVal: {\"title\":\"this is title\"}"]]

指令中给出的表达式(即my-params="{title: 'this is title'}")试图覆盖指令范围属性(总是在1.2中创建一个新对象,因此无限摘要)。

答案 1 :(得分:0)

link函数仅在directive初始化时执行一次。 因此myParams.title函数内部link的值在此阶段被赋值(但稍后会被覆盖)

之后,您已更新属性中的my-params值(将单独监视并按角度更新)。因此,属性中的值是myParam.title的最新值,它会反映在UI中。

如果你想设置一个新值,你可以在link里面有一个click功能(或其他事件处理程序),它可以改变这样的值:

控制器中的

$scope.myparams = {title: 'this is title'};
UI中的

<div my-directive my-params="myparams"></div>
指令中的

.directive('myDirective', function () {
    return {
        restrict: 'A',
        template: '<span> Title: {{myParams.title}} </span>',
        scope: {
            myParams: '='
        },
        link: function ($scope,element) {
            // the new value is not reflected in ui

            element.click(function(){
                $scope.myParams.title = 'this is myDirective';
                $scope.$apply();
            })
        }
    };
});