如何从子指令更新控制器范围变量?

时间:2015-10-31 17:34:18

标签: angularjs angularjs-directive angularjs-scope

我在控制器$scope上的变量从绑定到这些变量的指令中遇到了麻烦。例如,每当我移动鼠标时,我都会尝试使用setter函数更新值,但值永远不会更新。

我在这里做了一个小提琴:http://jsfiddle.net/23hdsueb/

如何在我的指令中设置父作用域的变量?

HTML:

<body ng-app="testApp" ng-controller="TestController">
    <p>
        outside directive
    </p>
    <input type="text" name="name" ng-model="obj.value">
    <p>
        value: {{obj.value}}
    </p>
    <test value="obj.value" set-value="setValue"></test>
</body>

JS:

angular.module('testApp', [])

.controller('TestController', ['$scope', function ($scope) {
    $scope.obj = {
        value: 'initial value'
    };
    $scope.setValue = function (val) {
        $scope.obj.value = val;
    };
}])

.directive('test', ['$document', function ($document) {
    return {
        restrict: 'E',
        scope: {
            value: '=',
            setValue: '='
        },
        template: '<div class="test">inside directive<br>value: {{value}}</div>',
        link: function (scope, element, attrs) {
            $document.on('mousemove', function (event) {
                scope.setValue(event.pageX + ' : ' + event.pageY);
            });
        }
    };
}]);

2 个答案:

答案 0 :(得分:1)

很抱歉在第一次尝试时没有给出正确的答案,我没有正确理解这个问题。答案是你的整个代码是正确的,除了你缺少一行代码。通常你不需要添加它,但你需要在这里添加它。

$document.on('mousemove', function (event) {
  scope.setValue(event.pageX + ' : ' + event.pageY);
  scope.$apply();
});

虽然$ document是一个愤怒的变量,但是$ document.on并不是将事件处理程序附加到事件的有效方式。

为什么遵循愤怒的方式是好的?因为它们在命令完成时自动运行范围。$ apply()。 apply()函数触发一个消化周期,负责角度的功率。许多事物中的摘要周期,检查是否存在需要更新的绑定变量。

如果您使用ng-mousemove,那么您将不再需要范围。$ apply()行,因为ng-mousemove指令会在触发时触发摘要周期。

答案 1 :(得分:0)

您缺少的是,通过指令调用控制器功能的语法/或/如何在指令属性中调用方法: TL:DR你可以通过漂亮的explanation about same by Dan Wahlin

在你的指令中:

.directive('test', ['$document', function ($document) {
    return {
        restrict: 'E',
        scope: {
            value: '=',
            setValue: '&'//for function it should be &
        },
        template: '<div class="test">inside directive<br>value: {{value}}</div>',
        link: function (scope, element, attrs) {
            $document.on('mousemove', function (event) {
                //argVal should be exact name in the function call mentioned in directive's attribute
                scope.setValue({argVal: event.pageX + ' : ' + event.pageY});
            });
        }
    };
}]);

您的指令使用应如下:请注意: argVal 应与链接function调用中的函数调用完全匹配

<test value="obj.value" set-value="setValue(argVal)"></test>

详情请参阅:SO question