【问题标题】:$http Service Not Updating View$http 服务未更新视图
【发布时间】:2017-12-11 23:12:05
【问题描述】:

我有两个控制器,一个嵌套在另一个控制器中。 ParentController 有一个我在 ChildController 中使用的对象,因为它可以直接在 child 中使用。现在,在孩子中,我正在调用 $http 服务,然后更新这个对象。我认为它应该更新视图。

我尝试调用 $scope.$apply() 承诺成功函数,但我想我不太明白如何使用这个函数。如何在不刷新页面的情况下更新 DOM?

我还阅读了有关在 $scope.$apply() 中调用 $http 服务的信息。该怎么做?

 $scope.addVideo = function (data) {
            console.log('scope tutorial', tutorial);
            $http.post('/tutorials/' + tutorial.id + '/videos/', $scope.formData)
            .then((response) => {
                $window.tutorial.videos.push(response.data.video);
                window.location = '/tutorials' + tutorial.id;
            })
}

现在,在 UI 中,我使用的是 TutorialsController,它负责添加教程。我的意思是它是一种形式,它只适用于形式。然后是本教程中显示视频的 VideoController。

<div ng-controller="TutorialsController">
// add video in this tutorial logic
<ol ng-repeat="vid in tutorial.videos" ng-controller="VideoController">
<li>{{vid.title}}</li><button>Delete</button>
</ol>
</div>

当父级添加视频时,我想更新子级,当子级 VideoController 使用删除按钮删除视频时,我想将其从父级范围中删除。

【问题讨论】:

  • 请记住,在大多数地方(控制器、服务),处理事件的指令已经为您调用了 $apply。只有在实现自定义事件回调或使用第三方库回调时,才需要显式调用 $apply。
  • 当询问由您的代码引起的问题时,如果您提供人们可以用来重现问题的代码,您将获得更好的答案。见How to create a Minimal, Complete, and Verifiable example
  • 很大程度上取决于您对“更新对象”使用的方法
  • 没有更多信息,tbis 的问题太宽泛了。两个控制器是如何设置的? ng-controller 还是作为 AngularJS 组件的控制器?他们是否使用controllerAs 语法来实现?涉及的作用域是隔离作用域还是继承作用域?
  • 我很抱歉这个问题。我已经用一些 sn-p 代码更新了这个问题。

标签: angularjs angularjs-http


【解决方案1】:
$scope.addVideo = function (data) {
    console.log('scope tutorial', tutorial);
    $http.post('/tutorials/' + tutorial.id + '/videos/', $scope.formData)
    .then((response) => {
        ̶$̶w̶i̶n̶d̶o̶w̶.̶t̶u̶t̶o̶r̶i̶a̶l̶.̶v̶i̶d̶e̶o̶s̶.̶p̶u̶s̶h̶(̶r̶e̶s̶p̶o̶n̶s̶e̶.̶d̶a̶t̶a̶.̶v̶i̶d̶e̶o̶)̶;̶ 
        $scope.tutorial.videos.push(response.data.video);
        ̶w̶i̶n̶d̶o̶w̶.̶l̶o̶c̶a̶t̶i̶o̶n̶ ̶=̶ ̶'̶/̶t̶u̶t̶o̶r̶i̶a̶l̶s̶'̶ ̶+̶ ̶t̶u̶t̶o̶r̶i̶a̶l̶.̶i̶d̶;̶
    })
}

【讨论】:

    【解决方案2】:

    考虑到您没有编写完整的代码,我进行了一些猜测并为您准备了一些东西。你应该尽量不要使用 $scope.$apply,除非你完全确定你需要它,大多数时候 Angular 会为你触发摘要循环,所以没有必要使用 $scope.$apply。主要的是您可以使用$scope.$emit 来发出要删除的视频的值。

    如果您不熟悉 $emit,请查看此以获取更多详细信息(您也可以查看 $broadcast,它将从上到下发送事件 - 与 $emit 相对): https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$emit

    所以,在你的情况下,输入你的 VideoController 类似的东西:

    $scope.deleteVideo = function(video) {
        $scope.$emit('deleteVideo', video);
      };
    

    在您的TutorialsController 中,您将需要收听与此类似的更改 - 数据参数将从子控制器获取您的视频对象:

    $scope.$on('deleteVideo', (event, data) => {
        $scope.tutorial.videos = $scope.tutorial.videos.filter(video=>!angular.equals(video,data));
      });
    

    以上内容只会从 $scope 中删除视频 - 因此您需要添加 $http 逻辑。

    我简化了你的视频,我在每个视频对象上添加了someProperty 和用于显示标题的title,现在一切都只是为了展示如何通过 $emit/$broadcast 在控制器之间轻松通信。

    这是小提琴上的简化示例:https://jsfiddle.net/pegla/d1rb96us/2/

    另外,我建议您查看 Todd Motto 的样式指南并开始使用基于组件的架构。目前最好的在线AngularJS风格指南:https://github.com/toddmotto/angularjs-styleguide

    希望对您有所帮助。 干杯!

    【讨论】:

    • 谢谢!你的 cmets 很有用!
    猜你喜欢
    • 2014-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-28
    • 2016-07-08
    • 1970-01-01
    • 2018-08-08
    • 1970-01-01
    相关资源
    最近更新 更多