在努力清理范围汤的过程中立即查看不再更新

时间:2016-11-19 19:46:07

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

我已成为自我施加范围汤的牺牲品,我正在采取措施纠正这个问题。我采用了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()方法&#34;传递&#34; _this的值仍然是引用 控制器
  • 使用函数调用创建的闭包,所以&#34; _this&#34;仍引用控制器
  • 使用$ scope。$ apply() - 我每次尝试整合此总是返回错误,$ apply()未定义。

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

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

1 个答案:

答案 0 :(得分:0)

检查您的HTML - 您有2个<section>个标签,其中包含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>

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