1

这里的目标是有两个不同的指令,技术上是兄弟姐妹共享功能。我会用其中一个,另一个里面没有一个角度控制器继承范围问题

但是,第二条指令将具有第一条的所有功能并添加一些小的添加。因此,我希望从“Parent”指令继承到“Child”的功能。

我通过重新使用Child上的Parent的相同指令定义对象来实现此目的,但要更改的控制器/模板字段除外。

这一切都运行良好,直到我从我的ParentDirCtrl打到观察者。由于某种原因,观察者似乎设置正确,观察mydir.obj1,但不知何故内部观察者回调函数mydir.obj1变得未定义。

我假设一些关于_.extend/$controller正在改变如何$scope的工作所以mydir.obj1没有在ParentDirCtrl定义,但我不知道为什么会是这样。

Plunk

angular.module('plunker', []) 

// lodash 
.constant('_', _) 

.controller('MainCtrl', function($scope, $timeout) { 
    $scope.obj = { 
    name: 'John', 
    age: 30, 
    }; 
}) 


.controller('ParentDirCtrl', function($scope) { 
    var mydir = this; 

    mydir.doStuffInParent = function() { 
    alert('executed from the parent directive'); 
    } 

    $scope.$watch('mydir.obj1', function() { 
    // ==================================== 
    //    ERROR 
    // Why is 'mydir.obj1' undefined when 
    // occupation is set? 
    // ==================================== 
    mydir.obj1.occupation = 'Meteorologist'; 
    }); 
}) 


.directive('parentDirective', parentDirective) 


.directive('childDirective', function() { 
    // borrow the directive definition object from the parent directive 
    var parentDDO = parentDirective(); 

    // uodate the template and controller for our new directive 
    parentDDO.template = [ 
    '<div>', 
     '<p ng-click="mydir.doStuffInParent()">{{mydir.obj1.name}}</p>', 
     '<p ng-click="mydir.doStuffInChild()">{{mydir.obj1.age}}</p>', 
    '</div>' 
    ].join(''); 

    parentDDO.controller = function($scope, $controller, _) { 
     // extend 'this' with the Parent's controller 
     var mydir = _.extend(this, $controller('ParentDirCtrl', { $scope: $scope })); 

     mydir.doStuffInChild = function() { 
     alert("executed from the child directive"); 
     }; 
    }; 

    return parentDDO; 
}); 


// this will be moved to the top during declaration hoisting 
function parentDirective() { 
    return { 
    restrict:'E', 
    scope: {}, 
    bindToController: { 
     obj1: '=', 
    }, 
    template: '<div>{{mydir.obj1}}</div>', 
    controller: 'ParentDirCtrl', 
    controllerAs: 'mydir', 
    }; 
} 
+0

如果它们基本相同,为什么不能通过设置属性来区分功能? – charlietfl

+0

孩子将会有一些功能覆盖父母的功能,然后是父母不需要的功能。另外,它还会有一些观察者来查看父项中不存在的属性。这就是说,父母中的100%功能是儿童所需要的。需要很多条件来在单个指令中控制所有这些。 – diplosaurus

+0

'var mydir'是'this'用来自父控制器的属性扩展的。我的理解是,这是从另一个控制器继承的方式。 – diplosaurus

回答

1

obj1填充在儿童控制器实例 - 这就是为什么mydir.obj1父观察者是不明确的。您可以通过直接范围或通过传递到观察者的参考访问obj1

$scope.$watch('mydir.obj1', function(val) { 
    $scope.mydir.obj1.occupation = 'Meteorologist'; 
    // or 
    val.occupation = 'Meteorologis'; 
}); 

没有继承范围在这里 - 两个控制器在同一范围内运行。 Controller-AS语法让你感到困惑 - 我会摆脱它来使事情更清晰。

+0

谢谢,我把你的建议和更新沟渠控制器 - 作为语法。错误消失了,但现在观察者根本没有触发:https://plnkr.co/edit/oVCoPW?p=preview看起来应该在观察者应该触发的'$ timeout'之后。 – diplosaurus

+1

要捕捉'angular.copy'所做的更改 - 将'$ watch'方法的第三个参数('objectEquality')设置为'true'。 'angular.copy'不会更改目标的引用。 –

+0

啊,呵呵。应该一直使用$ watchCollection。谢谢! – diplosaurus