JavaEar 专注于收集分享传播有价值的技术资料

Best practice to update parent or other simultaneous Angular controllers?

Forgive if this is general, but I'm looking for an approach and I'm new to Angular. Say I have a main controller and a runtime created modal controller. Let them be WidgetCtrl and NewWidgetModalCtrl.

I want to create a Widget and send that data to the server using $resource.save(). It returns some data and we close the "New Widget Modal" (it gets $destroyed). How would I add this widget to the list in WidgetCtrl?

Some say to use a shared service/factory. But the problem is that these are singletons. I may want two separate lists of Widgets. I might want a widgets in the cart List and a popular List. If I use a singleton, I'm pretty sure its a static list accross all controllers. I'd have to duplicate very similar classes to have same structured but dissimilar data. ....? It works well for something like a Session as seen in this example: Model Shared Between Two Controllers but not well for something like browsing and selecting from various lists of same-typed objects.

How can I have abstract Widget definition, and build and control lists between controllers? The Angular discussions seem to consider x-controller communication by modification of parent $scope objects a bad practice. And this is doubly bad in this situation because I can have any number of modals appearing.

Some say to do $emit and then refresh the data in the "parent" scope. But then this causes all the data to get reloaded from the server, when all we did was add a single widget.

   $scope.$watch( 'widgets', function(){ 
        this.widgets = Widget.query(); //get all widgets
    });

I guess what I'm looking for here is an instance variable that extends a base model definition that can be referenced in both locations and added to via $resource or in-app, as opposed to a singleton who would always update any list of that type. Am I just confused here, should I go ahead and make a (factory)PopularWidgetModel and a (factory)CartWidgetModel? Seems tedious. Maybe I don't quite understand how this would apply in my situation.

1个回答

    最佳答案
  1. I'm a little confused, but I'll take a stab at an answer.

    When the widget data comes back from $save, you can use .then() to add it to $scope.widgets in widgetCtrl. If you wanted to share this list between controllers (that have no hierarchical relationship to eachother), this widget list should be in a service that you inject into each controller. Each controller will then have

    $scope.widgets = widgetService.widgetList;
    

    where widgetList is updated by your calls to $resource functions.

    Anywhere you want to show this list of widgets, you would use ng-repeat="widget in widgets".

    If you have different lists, like one for cart and one for popular, then you might find a way to include "inCart" or "inPopular" as properties in your widget object. Then you can use

    <div ng-repeat="widget in widgets" ng-if="widget.inCart">
    

    and

    <div ng-repeat="widget in widgets" ng-if="widget.inPopular">
    

    or

    <div ng-repeat="widget in widgets | filter:{inCart:true}">
    

    and so on. I'm not 100% sure on the syntax for the filter, but something like that can be done.

    I don't think you need two factories here because it's the same data; but like you say, you might want to show it in different ways, or partial list here, partial list there.

    Also, directives might help here because it sounds like you want a "abstract widget definition", and to me, that sounds like a directive. They have their own controllers and can either have an isolated scope, or share the scope of their parent controller just as easily as using $scope.parentVar.

    Hope that helps.