【问题标题】:View No Longer Updating Immediately in Efforts to Clean Up Scope Soup查看不再立即更新以清理范围汤
【发布时间】:2016-11-20 05:31:50
【问题描述】:

我已经成为自我强加的 $scope 汤的受害者,我正在采取措施纠正这个问题。我正在采用 Josh Carroll 在他的文章中所写的一些方法:
http://www.technofattie.com/2014/03/21/five-guidelines-for-avoiding-scope-soup-in-angular.html.

也可以在此处找到有关此方法的更多信息:
https://johnpapa.net/do-you-like-your-angular-controllers-with-or-without-sugar/

这种方法因其更加面向对象的风格已经成为一股新鲜空气,并带来了一种更清洁、更易于管理的方法。

但是,我遇到了一个具体问题:视图没有像以前那样立即更新。我怀疑它与 _this 所引用的内容有关:$scope vs controller vs window

当 ctrl.addTask() 被调用时,一个新的任务记录被成功插入到数据库中。但是,新任务不会通过 ng-repeat 立即出现在视图中(通过新的 getTasks() 调用),并且只会在手动页面刷新后显示。我在页面上放置了另一个按钮(仅用于测试目的)进一步加深了我的困惑,该按钮专门调用 getTasks(),并且每次都会立即使用新任务更新视图。

index.html:

<section ng-controller="TaskCtrl as ctrl">
    <div class="container">
        <form name="addTaskForm">
            <div class="form-group">
                <input type="text" class="form-control" name="taskName" ng-model="ctrl.addTaskData.taskName" placeholder="New Task Name" ng-focus="addNewClicked">
                <div class="form-group-btn">
                    <button class="btn btn-default" type="submit" ng-click="ctrl.addTask();"><i class="glyphicon glyphicon-plus"></i>&nbsp;Add New Task</button>
                </div>
        </form>
    </div>
</section>
<section ng-controller="TaskCtrl as ctrl">
    <div class="row" ng-repeat="task in ctrl.tasksData" repeatdirective>
        <div class="col-xs-12 vcenter">
            <a href="/task/{{ task.id }}">{{ task.name || "Error - Task Names Should Not be Empty" }}</a>
        </div>
    </div>
</section>

app.js

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

var TasksCtrl = function($filter, $scope, $window, $http, $location) {

    var _this = this;

    _this.getTasks = function() {
        var request = $http({
            method      : 'POST',
            url         : '/handler.php',
            data        : {
                'action' : 'getAllTasks'
            },
            headers : {
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            responseType: 'json'
        }).then(function successCallback(response) {
            _this.tasksData = response.data;
            console.log( "getTasks() successCallback" );
        }, function errorCallback(response) {
            console.log( "getTasks() errorCallback" );
        });
    };
    _this.getTasks();

    _this.addTaskData = {};
    _this.addTask = function() {
        var request = $http({
            method      : 'POST',
            url         : '/handler.php',
            data        : {
                'action'                : 'addTask',
                'taskName'              : _this.addTaskData.taskName,
                'startDate'             : '',
                'endDate'               : ''
            },
            headers : {
                'Content-Type': 'application/x-www-form-urlencoded' 
            },
            responseType: 'json'
        }).then(function successCallback(response) {
            console.log("addTask() successCallback");
            _this.getTasks();
            _this.addTaskForm.$setPristine();
            _this.addTaskData = {};
        }, function errorCallback(response) {
            console.log("addTask() errorCallback");
        });         
    };
}

TaskCtrl.$inject = ['$filter', '$scope', '$window', '$http', '$location'];
app.controller('TaskCtrl', TaskCtrl);

我知道建议将 http 删除到它自己的服务,该服务绑定回控制器。这是我进一步清理 $scope 汤的下一步工作之一。

为解决问题尝试的补救措施:

  • 使用 .bind() 方法将 _this 的值“传递”到仍然引用 控制器
  • 使用函数调用创建的闭包,因此“_this”仍然引用控制器
  • 使用 $scope.$apply() — 我所做的每一次集成尝试总是返回 $apply() 未定义的错误。

请注意,上面列出的三种方法中的任何一种都可能未正确实施。另请注意,大部分代码已被修剪以专注于特定问题。

非常感谢任何和所有的指导或反馈!

【问题讨论】:

    标签: javascript angularjs oop angularjs-scope angularjs-http


    【解决方案1】:

    检查您的 html - 您有 2 个 &lt;section&gt; 标记和 2 个 ng-controller=TaskCtrl as ctrl,因此您有 2 个 TaskCtrl 实例。首先是处理添加新任务,另一个是负责打印它们。

    当您调用addtask 时,会从第一个控制器调用getTask,并在第一个控制器中更新taskData

    当您只有一个ng-controller 时,它会起作用。

    <section ng-controller="TaskCtrl as ctrl">
        <div class="container">
            <form name="addTaskForm">
                <div class="form-group">
                    <input type="text" class="form-control" name="taskName" ng-model="ctrl.addTaskData.taskName" placeholder="New Task Name" ng-focus="addNewClicked">
                    <div class="form-group-btn">
                        <button class="btn btn-default" type="submit" ng-click="ctrl.addTask();"><i class="glyphicon glyphicon-plus"></i>&nbsp;Add New Task</button>
                    </div>
            </form>
        </div>
        <div class="row" ng-repeat="task in ctrl.tasksData" repeatdirective>
            <div class="col-xs-12 vcenter">
                <a href="/task/{{ task.id }}">{{ task.name || "Error - Task Names Should Not be Empty" }}</a>
            </div>
        </div>
    </section>
    

    您还可以使用服务来存储数据并将其注入两个控制器,这样数据将仅存储在此服务中并且可以共享。

    【讨论】:

    • 对!当然!太感谢了。现在我正在愉快地清理剩下的这个烂摊子。仅供参考,在同一页面上拥有同一个控制器的多个实例是因为我实际上脱离了该控制器并进入另一个控制器。这已从显示的示例代码中删除。我将考虑将这些其他控制器嵌套在此处显示的内容中,或者将它们分开(如上所示)并按照您在创建服务以解耦数据时的建议进行操作。大概是后者。再次感谢!
    猜你喜欢
    • 2021-10-08
    • 2020-05-22
    • 1970-01-01
    • 1970-01-01
    • 2014-06-11
    • 1970-01-01
    • 2018-11-08
    • 2023-04-09
    • 1970-01-01
    相关资源
    最近更新 更多