【问题标题】:Is it Possible to Update Parent Scope from Angular Directive with scope: true?是否可以使用范围:true 从 Angular 指令更新父范围?
【发布时间】:2013-05-30 20:46:59
【问题描述】:

我需要从指令中的父控制器继承范围。我不一定要离开范围:假。我也不一定想使用隔离范围,因为它需要做很多工作才能正确链接我关心的值(想想父控制器中的很多值)。

如果我想更新父作用域,在我的指令中使用 scope:true 是否有意义?

<div ng-controller="MyCtrl">
      Hello, {{name}}!
        <my-directive></my-directive>
</div>
var myApp = angular.module('myApp',[]);

//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});

function MyCtrl($scope) {
    $scope.name = 'Dave';
}


myApp.directive('myDirective', function() {
    return {
        scope: true,
        restrict: 'EA',
        link: function(scope, elem, attrs) {
            scope.updateName = function(newName) {
                console.log('newName is: ' + newName);
                scope.name = newName;
            }
        },
        template: '<input ng-model="updatedName" placeholder="new name value"> <button ng-click="updateName(updatedName)">Update</button>'
    }
})

请查看fiddle

【问题讨论】:

    标签: angularjs angularjs-directive angularjs-scope


    【解决方案1】:

    虽然@user1737909 已经引用了 SO 问题来阅读(What are the nuances of scope prototypal / prototypical inheritance in AngularJS?,它将解释问题并推荐各种解决方法),但我们通常会尝试在 SO 上给出答案。

    所以,你的小提琴不起作用的原因是当一个原始类型(即字符串、数字或布尔类型)被写入时——例如,scope.name = newName——“写入”总是去本地范围/对象。换句话说,子作用域拥有自己的name 属性,它会隐藏同名的父属性。解决方法是在父作用域中使用对象,而不是原始类型。然后子作用域将获得对该对象的引用。对对象属性的任何写入(无论是来自父对象还是子对象)都将写入该对象。 (子作用域没有得到自己的对象。)

    $scope.obj = {name: 'Dave'};
    

    然后在你的指令中:

    scope.obj.name = newName;
    

    和 HTML:

    Hello, {{obj.name}}!
    

    fiddle

    【讨论】:

    • 只了解这部分,而不是更普遍地了解范围如何工作,恕我直言,这不是一个好主意。
    • 这就是我要找的。这是将它(或大部分)粘合在一起的部分。谢谢,马克的详细回答,这真的很棒。
    • 抱歉挖掘了一个旧线程,但是,在材料角度可以使用例如 mdSelect 指令,如下所示:
    • 那么这如何工作呢? adamalbrecht.com/2013/12/12/… 指令覆盖 show 但仍保留对 modalShown 的引用。
    【解决方案2】:

    作用域继承并不意味着设置子项的值就是设置其父项的值。

    不要在子作用域上执行scope.name = newName,而是向父作用域添加一个方法,该方法将在父作用域上执行相同的工作,并从子作用域调用它,因为子作用域继承了此方法。

    【讨论】:

    • 这就是我所使用的,提供 setter 方法似乎比允许直接访问父范围的属性更干净。
    【解决方案3】:

    在你的链接函数中,你可以像这样写到父作用域(全局“$scope”作用域):scope.$parent.name = newName;

    【讨论】:

      猜你喜欢
      • 2015-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-06
      • 2016-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多