拆分一个控制器的HTML组件会导致控制器停止工作

时间:2013-03-25 04:37:07

标签: javascript angularjs

如果我创建两个div,两个都由同一个控制器控制,Angular的控制器似乎停止更新我的视图。

我已经汇总了一个简单的例子来证明这一点。查看示例here on JSFiddle最简单,但我也在下面发布代码。

HTML

<div ng-app='App'>
    <div ng-controller="MyCtrl">
        <form>
            <input type="text" ng-model="search.query"></input>
            <button ng-click="search.submit()">Submit</button>
        </form>
    </div>
    <div ng-controller="SomeOtherCtrl">
        {{sampleText}}
    </div>
    <div ng-controller="MyCtrl">
        <button ng-click="search.reset()">Reset Form</button>
    </div>
</div>

JS

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

function MyCtrl($scope)
{
    $scope.search = {
        query : 'foobar',
        submit : function() {
            this.query = 'Submitted';
            console.log(this.query);
        },
        reset : function() {
            console.log('resetting');
            this.query = '';
        }
    };
}

function SomeOtherCtrl($scope) {
    $scope.sampleText = 'other controller text';
}        

提交按钮工作正常,但是当我单击“重置”按钮时,我看到resetting已登录控制台,但我的视图(表单输入)未更新。

为什么会这样?在我正在进行的当前项目中,我被迫这样做,因为介于两者之间的某些HTML属于另一个控制器。我该如何解决这个问题?

3 个答案:

答案 0 :(得分:2)

angular中的控制器定义实际上是Class / Constructor而不是Object。引用控制器的HTML中的每个位置,在编译阶段,angular使用定义的控制器类创建一个新的控制器对象。因此,您可以使用相同的控制器类来引用多个范围。

您可能已经听说过Angular中的服务,而这正是您需要使用它们来解决它的地方。您正在使用的search是一个由两个控制器实例共享的公共对象(注意,该类是相同的MyCtrl但是通过输入两个ng-controller="MyCtrl",您要求Angular创建两个实例MyCtrl)。因此,这两个对象可以访问两个不同的范围,当它们被创建时,两个不同的范围设置有两个不同的搜索对象。当您单击重置时,将调用其他search个对象reset,这意味着在第一个MyCtrl范围内没有任何操作。这就是您的代码无法按预期工作的原因。

现在请注意,角度服务是单身人士。因此,如果您在多个位置引用它们,则可以访问同一个对象。因此,在不同的控制器(实例)中重置仍将重置相同的对象。

这是一个适用于您的代码的插件。

http://plnkr.co/edit/zynAdS9hg8DUZDnlnYFm?p=preview

答案 1 :(得分:0)

我不知道angularjs是如何工作的,但是如果你把第二个输入<input type="text" ng-model="search.query"></input>放在重置按钮附近,这个输入就会被更新。 输入应该在同一个div控制器内吗? 它会帮助你解决问题吗?

答案 2 :(得分:0)

查看您的示例,您似乎缺少重置按钮的表单标记。从角度来看,如果你可以使用一个外部div为controller =“MyCtrl”,你有一个带有两个按钮的表单 - submit()和reset(),并在外部div你把你的嵌套控制器“SomeOtherCtrl”然后它应该完美地工作