角度控制器继承范围问题

时间:2016-07-20 21:20:33

标签: javascript angularjs angularjs-scope prototypal-inheritance

这里的目标是有两个不同的指令,技术上兄弟姐妹共享功能。我将使用一个另一个,而不是一个中。

但是,第二个指令将具有第一个指令的所有功能,并带有一些小的附加功能。因此,我希望继承的功能从“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',
  };
}

1 个答案:

答案 0 :(得分:1)

子控制器实例上填充了

obj1 - 这就是父观察者中未定义mydir.obj1的原因。您可以直接通过范围或使用传递给观察者的参考来访问obj1

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

此处没有范围继承 - 两个控制器都在相同的范围内运行。 Controller-AS 语法让你感到困惑 - 我会把它弄清楚以使事情变得更清楚。