10

我一直在试图找出解决方案,但我认为我遇到了死胡同。

所以这是我的指令

directives.directive('postprocess', function($compile)
{
    return {
        restrict : 'E',
        require: '^ngModel',
        scope: {
            ngModel: '='
        },
        link: function(scope, element, attrs) {
            var parsed = scope.ngModel;
            el = $compile(parsed)(scope);
            element.html("");
            //add some other html entities/styles.
            element.append(el);
            console.log(parsed);
        }  
    };
});

html

<postprocess ng-model="some_model.its_property" style="padding-top: 10px;" />

在控制器的某个地方,我更新了模型属性

some_model.its_property = 'Holla';

但它不会更新相应的指令。它在加载时完美运行,这告诉我它可能不完全是范围问题。

4

3 回答 3

16

它要简单得多,因此我删除了您在那里的一些额外代码。

请查看下面的代码或正在运行的Plunker

<!doctype html>
<html lang="en" ng-app="myApp">
    <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>

    <script>
        var myApp = angular.module('myApp', []);
        myApp.directive('postprocess', function ($timeout) {
            return {
                restrict : 'E',
                transclude: 'true',
                scope: {
                    myVariable: '='
                },
                link: function(scope, element, attrs) {
                    $timeout(function () {
                        scope.myVariable = 'Bye bye!'
                    }, 200);
                }  
            };
        });

        myApp.controller('myAppCtrl', ['$scope', '$timeout', function ($scope, $timeout) {
            $scope.myVariable = {
                value : 'Holla'
            };

            console.log($scope.myVariable.value); // -> prints initial value
            $timeout(function () {
                console.log($scope.myVariable.value); // -> prints value after it is changed by the directive
            }, 2000);
        }])
    </script>

    </head>
    <body ng-controller="myAppCtrl">
        <postprocess my-variable="myVariable.value" style="padding-top: 10px;" />
    </body>
</html>
  1. 控制器将初始值设置为“Holla”
  2. 该指令通过my-variable属性接收该值
  3. scope.myVariable使用两种方式数据绑定对更新$scope.myVariable主控制器所做的任何更改
  4. 几秒钟后$scope.myVariable变为“再见”
  5. 看看你的 console.log

$watch 和 $apply

Angular 的双向数据绑定是 Angular 中所有出色的根源。但是,这不是魔术,在某些情况下,您需要将其推向正确的方向。

当您使用 ng-model、ng-repeat 等将值绑定到 Angular 中的元素时,Angular 会在该值上创建一个 $watch。然后,每当作用域上的值发生变化时,所有观察该元素的 $watches 都会执行,并且所有内容都会更新。

有时,通常当您编写自定义指令时,您必须在范围值上定义自己的 $watch 以使指令对更改做出反应。

另一方面,有时您在某些代码中更改了范围值,但应用程序不会对其做出反应。在你的代码片段运行完毕后,Angular 检查范围变量的变化;例如,当 ng-click 在您的范围内调用一个函数时,Angular 将检查更改并做出反应。但是,一些代码在 Angular 之外,你必须自己调用 scope.$apply() 来触发更新。这在自定义指令的事件处理程序中最常见。

于 2013-10-01T17:30:08.260 回答
1

angularjs来自irc 和 dluz 的一些帮助已更新。虽然我希望有一种更简单的方法来调用指令,因为链接函数包含行为并且应该有一种方法来调用它。

http://jsfiddle.net/T7cqV/5/

于 2013-10-02T00:52:24.627 回答
1

确保使用点规则

http://jimhoskins.com/2012/12/14/nested-scopes-in-angularjs.html

于 2013-10-26T06:59:20.850 回答