Javascript AngularJS从$resource触发$scope.broadcast 介绍

Javascript AngularJS从$resource触发$scope.broadcast 介绍,javascript,angularjs,angularjs-directive,angularjs-service,Javascript,Angularjs,Angularjs Directive,Angularjs Service,我正在努力确保我正确使用angular应用程序的所有部分/所有正确的代码都在正确的位置 我偶然发现了这篇文章 它有一个示例应用程序,其中数据存储在服务内的数组中。我觉得应用程序的结构是合理的(但可能完全错误) 问题 在触发$resource操作时是否可以触发$broadcast,其方式与在此代码中更新阵列时触发$broadcast的方式相同 myApp.service( 'Book', function( $rootScope ) { var service = { books: [

我正在努力确保我正确使用angular应用程序的所有部分/所有正确的代码都在正确的位置

我偶然发现了这篇文章 它有一个示例应用程序,其中数据存储在服务内的数组中。我觉得应用程序的结构是合理的(但可能完全错误)

问题 在触发$resource操作时是否可以触发$broadcast,其方式与在此代码中更新阵列时触发$broadcast的方式相同

myApp.service( 'Book', function( $rootScope ) {

var service = {

    books: [
      { title: "Magician", author: "Raymond E. Feist" },
      { title: "The Hobbit", author: "J.R.R Tolkien" }
    ],
    addBook: function ( book ) {
        service.books.push( book );
        //console.log(service.books);
        $rootScope.$broadcast( 'books.update' );
    }
}

return service;

});
下面是一个实用的例子

奖金问题 如果我能做我所问的,那么另一个问题是我应该做什么?我认为替代方案是,所有与服务(以及其中的$resource)的交互都在控制器中进行(这是我到目前为止所做的)


如果您有任何想法或建议,我们将不胜感激。

是的,您可以按自己的要求去做。
$resource
将返回具有
$promise
属性的对象/数组。您可以使用此承诺来了解服务器请求何时成功/失败

在成功/失败处理程序中,根据需要执行
$rootScope.$broadcast()
。下面是一个使用
$resource
query()
方法执行此操作的服务:

编辑

下面是完整的服务实现。注意你可以用很多方法给这只猫剥皮,所以这些只是一些例子

myApp.service( 'Book', function($rootScope, $resource ) {

var myResource = $resource('/books/:id', { id: '@id' } );
var books;    
var service = {   
    // this function broadcasts the result
    getBooks: function() {
        myResource.query(
            function(response) {
                $rootScope.$broadcast('it.worked', response);
            },
            function(error) {
                $rootScope.$broadcast('it.failed', error);
            }
        );
    },
    // this function returns the $resource and also keeps a copy
    // so someone else may get the data with getBooksResult()
    getBooks2: function() {
        books = myResource.query();
        books.$promise(
            function(response) {
                // if you still need to broadcast...
                $rootScope.$broadcast('it.worked');
            },
            function(error) {
                $rootScope.$broadcast('it.failed');
            }
        );
        return books;
    },
    getBookResult: function() {
        return books;
    }
}

return service;
});  
你应该这样做吗?

我不认为这样做有什么害处,但你至少应该考虑一下。您将使用
$broadcast()
从应用程序作用域层次结构的顶部到应用程序中的每个其他作用域的事件

这可能会将事件发送到根本不关心事件的作用域。请记住,应用程序中可能有许多作用域(由控制器/指令创建)。在大多数情况下,这可能不是什么大问题


$resource
的好处在于它返回一个空对象,稍后将用服务器响应填充该对象。通常情况下,您不需要广播结果:)使用资源返回值的视图将自动更新。需要值(或错误)的控制器可以使用
$resource
中的
$promise
,如上所示。

Hi Mate,非常感谢您的快速详细回复。你的例子并不完全符合我的要求(我说的是从服务内部而不是从控制器或指令进行广播),但是你关于$broadcast后果的评论让我认为这不是最好的解决方案。当您说“使用资源返回值的视图将自动更新”时,如果我从两个控制器访问相同的$resource服务,这将如何应用?如果我从一个控制器更新$resource,那么另一个控制器的视图似乎不会更新?@PaulParton我的示例只是服务的“主体”。我懒得写完整的服务。想象一下您的原始服务,但您也将
$rootScope
注入到该服务中。让我来编辑。。。您所描述的问题(与第二个控制器)正是为什么您应该将此代码放入服务中…@PaulParton更新了我的答案。请记住,我不知道您的确切用例,所以这段代码有点做作。您的两个控制器问题的解决方案在于执行类似于上述操作的服务。另一个想法是使用
$http
(因此
$resource
)的缓存功能。您可以通过
$http
缓存数据,并让控制器进行查询。稍后您可以清空缓存,以便下一个查询将命中服务器。啊,我知道您现在从哪里来,非常感谢您花时间添加所有额外的细节。也谢谢你关于http缓存的提示,看起来不错。