angularjs:从ng-switch中的控制器更改父作用域

问题描述 投票:5回答:4

因此,我可以通过子控制器更改模型值,但是当子控制器位于ng-switch中时,它不起作用,为什么?我创建了an example进行演示。

避免这种情况的一种方法是在型号名称中使用.,例如bunnies.kills。这是错误还是功能?

使用Angular 1.0.6

javascript angularjs angularjs-scope angularjs-controller angularjs-ng-switch
4个回答
6
投票

使用代码结构,在子控制器中,您需要更改:

$scope.$parent.kills++;

to

$scope.$parent.$parent.kills++;

说明MainCtrl的范围是SimpleParentCtrl的父范围,但是Step1CtrlStep2Ctrl的祖父母。正如其他人指出的那样,ng-switch创建了自己的范围,然后您的Step1CtrlStep2Ctrl各自创建了ng-switch的子范围。

:每次单击1或2按钮,ng-switch及其当前匹配的子控制器都会获得一个新的作用域。

Also:如果您碰巧正在Angular源中查找并且想知道ng-switch指令如何创建自己的没有scope属性的范围,答案是它是在其链接方法中手动完成的通过scope.$new()。指令ng-includeng-switchng-repeatng-view都以此方式创建新作用域,无论是在链接方法中还是在编译方法的返回链接函数中。

资源:

https://github.com/angular/angular.js/wiki/The-Nuances-of-Scope-Prototypal-Inheritancehttp://www.youtube.com/watch?v=ZhfUv0spHCY&feature=youtu.be&t=30m


3
投票

ng-switch创建自己的子范围,因此@ sh0ber的答案是使其工作的一种方式。通常,models should be referenced在控制器作用域(因此是引用对象)中,而不是原语。因此,使用.是“最佳实践”。

这不是错误,但也不是功能。这是使用原语的JavaScript prototypal inheritance works方法。


2
投票

我将对这个问题采取稍微不同的方法。

而不是使用$scope.$parent,我建议您将所有的兔子杀死逻辑移到共享服务/模型中。

此外,我会尽量避免引用父视图/控制器。引用父级可能会很难重用您的代码,并且随着项目的增长而调试起来会很痛苦。父母可以知道它的孩子是可以的,但是孩子应该对其父母几乎一无所知。

这里是更新的Plunk:http://plnkr.co/edit/PLDbfU8Fu7m59A42qdR6?p=preview

HTML

<body ng-controller="MainCtrl">
    <p>
        Dead bunnies: <strong>{{Elmer.deadWabbits}}</strong>
    </p>
    <div ng-controller="SimpleParentCtrl">
        <button ng-click="Elmer.killTheWabbit()">Kill from simple parent gun</button>
    </div>
    <hr>
    <div ng-switch="" on="step">
        <div ng-switch-when="first" ng-controller="Step1Ctrl">
            <button ng-click="Elmer.killTheWabbit()">Kill from 1 tab gun</button>
        </div>
        <div ng-switch-when="second">
            <div ng-controller="Step2Ctrl">
                <button ng-click="Elmer.killTheWabbit()">Kill from 2 tab gun</button>
            </div>
        </div>
    </div>
    <hr>
    <p>
        <button ng-click="changeStep('first')">1</button> <button ng-click="changeStep('second')">2</button>
    </p>
</body>

JS

angular.module('plunker', []).
service("Elmer", [function() {
    this.deadWabbits = 0;
    this.killTheWabbit = function() {
        this.deadWabbits++;
    };
}]).
controller('MainCtrl', function($scope, Elmer) {
  $scope.Elmer = Elmer;
  $scope.step = 'first';
  $scope.changeStep = function(name){
    $scope.step = name;
  };
}).
controller('SimpleParentCtrl', function() {}).
controller('Step1Ctrl', function() {}).
controller('Step2Ctrl', function() {});

1
投票

一种避免这种情况的方法是使用。以模型名称命名,例如bunnies.kills。这是错误还是功能?

已对此进行了多次解释:https://github.com/angular/angular.js/wiki/The-Nuances-of-Scope-Prototypal-Inheritance并在mhevery的视频中

© www.soinside.com 2019 - 2024. All rights reserved.