【问题标题】:Angular Factory Async Calls- Updating Controller?Angular Factory 异步调用 - 更新控制器?
【发布时间】:2014-01-23 01:36:54
【问题描述】:

我有一个控制器和工厂来处理列表。控制器需要获取工厂加载的列表并在视图中显示。我不能在工厂中有 getLists() 方法,因为这需要从 FireBase 异步加载。这是我的控制器代码-

angular.module('myApp.controllers', []).
  controller('ListCtrl', ["$scope","listFactory", function($scope, ListFactory) {
    $scope.lists = [];

    $scope.$on("list_update", function(snapshot)
    {
        console.log(snapshot);
    });

  }]).
  controller("EditListCtrl", ["$scope","listFactory", function($scope, ListFactory)
    {
        $scope.name = "";
        $scope.items = [];
        $scope.itemCount = 10;

        $scope.save = function()
        {
            var List = {"items":[]};
            for(var i = 0; i < $scope.itemCount; i++)
            {
                var item = $scope.items[i];
                if(item != null)
                {
                    List.items.push(item);
                }
                else
                {
                    alert("Please fill all items of the list.");
                    return false;
                }

                ListFactory.putList(List);
                $scope.items = [];
                $scope.name = "";
            }
        }
    }]);

listFactory 看起来像这样-

angular.module("myApp.factories", [])
    .factory("listFactory", [function()
    {
        var lists = [{"name":"test"}];
        var ListRef = new Firebase("https://listapp.firebaseio.com/");

        var factory = {};
        factory.getLists = function()
        {
            // this won't work
        }

        factory.putList = function(List)
        {
            ListRef.child("lists").push(List);
        }

        ListRef.on("child_added", function(snapshot)
        {
            // How do I get this back to the controller???
        });

        return factory;
    }]);

ListRef 将调度一个“child_added”事件,其中快照参数具有列表数据。我需要以某种方式将其返回给控制器。我想用事件来做到这一点,但我不确定如何在工厂和控制器之间做到这一点。我不想使用根范围,因为我认为这是不好的做法。

我是新手 - 任何帮助将不胜感激!

【问题讨论】:

    标签: angularjs asynchronous controller factories


    【解决方案1】:

    首先更新您的列表变量以拥有一个容器对象:

    var lists = { items: [{ name: 'test' }] };
    

    然后通过工厂暴露对列表的访问,例如:

    factory.getLists = function() {
        return lists;
    }
    

    然后在你的控制器中设置一个作用域变量:

    $scope.lists = ListFactory.getLists();
    

    然后,每当触发child_added 事件时,更新lists.items,来自控制器的$scope 应反映更改。

    【讨论】:

    • 我还建议您阅读以下内容:jimhoskins.com/2012/12/14/nested-scopes-in-angularjs.html
    • 好吧,它确实可以工作,但前提是我开始操纵视图。当页面加载时,它应该拉入 2 个列表,但只有当我开始输入其中一个输入框时才会这样做。知道为什么吗?
    • 只是猜测,我会说在视图更改之前不会运行初始列表抓取,或者在视图更改之前抓取列表但不绑定到 $scope。你能创造一个小提琴吗?
    • 花了一些时间从文件中编译,但这里是一个小技巧-jsfiddle.net/ZwT7g/1
    • 它不能在负载上工作的原因是因为firebase回调,同时更新正确的值是在通常的范围过程之外运行的。将$rootScope 注入您的工厂,并用$rootScope.$apply(function(){ ... }); 包裹child_added for 循环
    猜你喜欢
    • 2016-12-27
    • 2017-05-19
    • 1970-01-01
    • 1970-01-01
    • 2018-02-24
    • 2014-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多