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

Splitting HTML components for one controller causes controller to stop working

本文关键字:控制器 组件 停止工作 HTML 拆分 一个      更新时间:2023-09-26

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

我已经组合了一个简单的示例来演示这一点。在JSFiddle上查看示例最简单,但我也在下面发布了代码。

<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';
}        

提交按钮工作正常,但是当我单击Reset按钮时,我看到resetting登录到控制台,但我的视图(表单输入)没有更新。

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

angular中的控制器定义实际上是一个class/Constructor,而不是Object。在编译阶段,在HTML中每一个被引用的地方,angular都会使用定义好的控制器类创建一个新的控制器对象。因此,您可以使用同一个控制器类引用多个作用域。

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

现在请注意,在angular中,服务是单例的。如果你在多个地方引用它们你就能访问同一个对象。因此,在不同的控制器(实例)中重置仍然会重置相同的对象。

这是一个与您的代码一起工作的plunk。

http://plnkr.co/edit/zynAdS9hg8DUZDnlnYFm?p =预览

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

查看您的示例,似乎您缺少重置按钮的表单标签。从角度来看,如果你可以使用一个外部div控制器="MyCtrl",你有一个表单的两个按钮-提交()和重置(),并在外部div你把你的嵌套控制器"SomeOtherCtrl",那么它应该工作完美。