使用 Controller As 方法访问继承范围 [英] Accessing inherited scope with Controller As approach

查看:15
本文介绍了使用 Controller As 方法访问继承范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用定义控制器的原始方式,访问父级的作用域相当简单,因为子级作用域原型上继承自其父级.

app.controller("parentCtrl", function($scope){$scope.name = "父";}).controller("childCtrl", function($scope){$scope.childName = "子" + $scope.name;});<div ng-controller="parentCtrl">{{姓名}}<div ng-controller="childCtrl">{{childName}}

Controller-As 方法 似乎是推荐声明控制器的方法.但是对于 Controller-As,上述方法不再有效.

当然,我可以从视图中使用 pc.name 访问父作用域:

{{pc.name}}<div ng-controller="childCtrl as cc">{{cc.childName}}

我确实对此有一些问题(意大利面条式代码的可能性),但这个问题是关于从子控制器访问父作用域.

我能看到这个工作的唯一方法是:

app.controller("parentCtrl", function(){this.name = "父";}).controller("childCtrl", function($scope){$scope.pc.name = "" + $scope.name 的孩子;//或者$scope.$parent.pc.name = "child of " + $scope.name;//没有 $scope.name//没有 $scope.$parent.name});

所以现在,子控制器需要知道pc"——除了,这应该(在我看来)仅限于视图.我认为子控制器不应该知道视图决定声明 ng-controller="parentCtrl as pc" 的事实.

问:那么正确的方法是什么?

澄清:我不想继承父控制器.我希望继承/更改共享范围.所以,如果我要修改第一个例子,我应该能够做到以下几点:

app.controller("parentCtrl", function($scope){$scope.someObj = {prop: "not set"};}).controller("childCtrl", function($scope){$scope.someObj.prop = "改变";});

解决方案

经过研究,我得出以下认识:

<块引用>

Controller-As 方法不能替代使用 $scope.两者都有自己的位置,可以/应该明智地一起使用.

  1. $scope 顾名思义:即它定义了 $scope 上的 ViewModel 属性.这最适合与嵌套控制器共享范围,这些控制器可以使用 $scope 来驱动自己的逻辑或更改它.
  2. Controler-As 将整个控制器对象定义为具有命名范围的 ViewModel(通过控制器的别名).如果 View 决定是否要引用特定的控制器 ViewModel,这仅在 View(而非其他控制器)中效果最佳.

这是一个例子:

var app = angular.module('myApp', []);//然后控制器可以选择是否要修改继承的范围:app.controller("ParentCtrl", function($scope) {this.prop1 = {v:来自ParentCtrl的prop1"};$scope.prop1 = {v:由ParentCtrl在范围内定义"};}).controller("Child1Ctrl", function($scope) {}).controller("Child2Ctrl", function($scope) {//在这里,我不知道pc"别名this.myProp = $scope.prop1.v + ",并由 Child2Ctrl" 更改;});

<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.min.js"></script><body ng-app="myApp"><div ng-controller="ParentCtrl as pc"><div ng-controller="Child1Ctrl"><div>我知道pc"别名:{{pc.prop1.v}}</div>

<div ng-controller="Child2Ctrl as ch2"><div>我只关心我自己的ViewModel:{{ch2.myProp}}</div>

With the original way to define controllers, accessing the parent's scope was fairly trivial, since the child scope prototypically inherits from its parent.

app.controller("parentCtrl", function($scope){
   $scope.name = "Parent";
})
.controller("childCtrl", function($scope){
   $scope.childName = "child of " + $scope.name;
});

<div ng-controller="parentCtrl">
   {{name}}
   <div ng-controller="childCtrl">
      {{childName}}
   </div>
</div>

The Controller-As approach seems to be the recommended way to declare a controller. But with Controller-As, the above approach no longer works.

Sure, I can access the parent scope with pc.name from the View:

<div ng-controller="parentCtrl as pc">
   {{pc.name}}
   <div ng-controller="childCtrl as cc">
      {{cc.childName}}
   </div>
</div>

I do have some issues with this (potential for spaghetti code), but this question is about accessing the parent scope from the child controller.

The only way I can see this working is:

app.controller("parentCtrl", function(){
   this.name = "parent";
})
.controller("childCtrl", function($scope){
   $scope.pc.name = "child of " + $scope.name;
   // or
   $scope.$parent.pc.name = "child of " + $scope.name;

   // there's no $scope.name
   // and no $scope.$parent.name
});

So now, the child controller needs to know about "pc" - except, this should (in my mind) be restricted to the view. I don't think a child controller should know about the fact that a view decided to declare a ng-controller="parentCtrl as pc".

Q: What's the right approach then?

EDIT:

Clarification: I'm not looking to inherit a parent controller. I am looking to inherit/change the shared scope. So, if I was to amend the first example, I should be able to do the following:

app.controller("parentCtrl", function($scope){
   $scope.someObj = {prop: "not set"};
})
.controller("childCtrl", function($scope){
   $scope.someObj.prop = "changed";
});

解决方案

After researching, I came to the following realization:

Controller-As approach is NOT a substitute for using $scope. Both have their place, and can/should be used together judiciously.

  1. $scope does exactly what the name implies: i.e. it defines ViewModel properties on the $scope. This works best for sharing scope with nested controllers that can use the $scope to drive their own logic or to change it.
  2. Controler-As defines the entire controller object as a ViewModel with a named scope (via the controller's alias). This works best only in the View (but not other controllers), if the View decides if it wants to reference a specific controller ViewModel.

Here's an example:

var app = angular.module('myApp', []);

// Then the controllers could choose whether they want to modify the inherited scope or not:
app.controller("ParentCtrl", function($scope) {
    this.prop1 = {
      v: "prop1 from ParentCtrl"
    };
    $scope.prop1 = {
      v: "defined on the scope by ParentCtrl"
    };
  })
  .controller("Child1Ctrl", function($scope) {})
  .controller("Child2Ctrl", function($scope) {
    // here, I don't know about the "pc" alias
    this.myProp = $scope.prop1.v + ", and changed by Child2Ctrl";
  });

<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.min.js"></script>

<body ng-app="myApp">
  <div ng-controller="ParentCtrl as pc">
     <div ng-controller="Child1Ctrl">
        <div>I know about the "pc" alias: {{pc.prop1.v}}</div>
     </div>
     <div ng-controller="Child2Ctrl as ch2">
       <div>I only care about my own ViewModel: {{ch2.myProp}}</div>
    </div>
  </div>

这篇关于使用 Controller As 方法访问继承范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆