AngularJS指令的基本问题无法正常工作

时间:2014-03-08 12:50:49

标签: angularjs angularjs-directive angularjs-scope

我有以下 html

<!doctype html>
<html lang="en" ng-app="myApp">
<head>
    <meta charset="utf-8">
    <title>My AngularJS App</title>
    <link rel="stylesheet" href="css/app.css"/>
</head>
<body>

<div ng-controller="myCtrl">
    <cmp>
        <enhanced-textarea ng-model="name"></enhanced-textarea>
        <h3>{{name}}</h3>
        <notice></notice>
    </cmp>
</div>

<script src="lib/angular/angular.js"></script>
<script src="js/directives.js"></script>
<script src="js/controllers.js"></script>
<script src="js/app.js"></script>
</body>
</html>

我怀疑我的 app.js 存在问题:

'use strict';

angular.module('myApp', [
    'myApp.directives',
    'myApp.controllers'
]);

这是 controllers.js

'use strict';

angular.module('myApp.controllers', [])
  .controller('myCtrl', ['$scope', function($scope) {
        $scope.name = 'test';
  }]);

最后 directives.js

'use strict';

angular.module('myApp.directives', [])
    .directive('cmp', function () {
        return {
            restrict: 'E',
            controller: 'cmpCtrl',
            replace: true,
            transclude: true,
            scope: {
                name: '='
            },
            template: '<div ng-transclude></div>'
        };
    })
    .controller('cmpCtrl', ['$scope', '$element', '$attrs' , function ($scope, $element, $attrs) {
        $scope.$parent.$watch('name', function (newVal) {
            if (newVal) {
                $scope.$parent.updatedSize = newVal.length;
                console.log(newVal.length);
            }
        }, true);
    }])
    .directive('enhancedTextarea', function () {
        return {
            restrict: 'E',
            replace: true,
            transclude: true,
            template: '<textarea ng-transclude></textarea>'
        };
    })
    .directive('notice', function () {
        return {
            restrict: 'E',
            require: '^cmp',
            replace: true,
            scope: {
                updatedSize: '='
            },
            template: '<div>{{size}}</div>',
            link: function ($scope, $element, $attrs, cmpCtrl) {
                console.log(cmpCtrl);
                $scope.$parent.$watch('updatedSize', function (newVal) {
                    if (newVal) {
                        $scope.size = newVal;
                    }
                }, true);
            }
        };
    });

我知道,我的代码很臃肿,但我正在修剪它。忍受我。

我不明白为什么size元素中的notice模型属性未更新...

完整应用位于github here

1 个答案:

答案 0 :(得分:1)

问题是作用域继承,您的enhancedTextarea指令'作用域继承了控制器的name属性,因为它是未定义。但是一旦你改变了textarea值,它的属性就是创建,你改变了这个指令的范围属性后你改变了什么。

看看这个DEMO

当您检查控制台而不更改textarea时,您将看不到范围的name属性。当您输入内容时,您会看到已创建的属性覆盖父级的范围name属性。

当你更改这样的代码时,它可以工作:

<enhanced-textarea ng-model="name"></enhanced-textarea>
<cmp>
    <h3>{{name}}</h3>
    <notice></notice>
</cmp>

DEMO

为了创建松散耦合的代码,我建议您不要依赖$scope.$parent指令内部。您应该尝试使用指令绑定来绑定父属性。