angularJS工厂不在视图之间保存$ scope状态

时间:2015-04-27 17:40:22

标签: angularjs

所以我一定做错了。我已经阅读了有关此内容的帖子,此处的大多数建议都建议设置工厂以保留跨视图的范围数据。所以我已经建立了一个工厂来绑定从选项复选框收​​到的范围数据,但它不是跨视图的持久性。这里是有问题的代码..任何想法?感谢

我的模块

var app = angular.module('app', ['ngMaterial','ui.router']);

我的工厂

app.factory('Options', function() {
  var flavors = {};

  flavors.getFlavors = function() {
  return [
  { name: 'Vanilla', wanted: false },
  { name: 'Hazelnut', wanted: false },
  { name: 'Almond', wanted: false },
  { name: 'Caramel', wanted: false }]; 
  };

  return flavors;

});

我的控制器

app.controller('OrderFormController', function($scope, Options) {

  $scope.flavors = Options.getFlavors();

});

我的html选项标记

<md-list-item ng-repeat="flavor in flavors" 
              layout="row">
              <p> {{ flavor.name }} </p>
              <span flex></span>
              <md-checkbox aria-label="flavor.wanted"
                           class="md-accent" 
                           ng-model="flavor.wanted">
              </md-checkbox>
</md-list-item>

我的html产品标记

<md-card ng-repeat="item in items.results" 
         ng-controller="OrderFormController">
     <img ng-src="{{item.img}}" 
          class="md-card-image" 
          alt="">
          <md-card-content class="content">
              <h2 class="md-title">{{ item.name }}</h2>
              <h4>{{ item.price | currency }}</h4>
              <p class="container" 
                 ng-class="{show: show}">
                 {{ item.desc}}
              </p>
              <md-button class="md-primary" 
                         ng-click="show = !show"
                         ng-show="!show">
                         <md-icon md-svg-icon="img/icons/unfold-more.svg"></md-icon>
                         <span>Show More</span>
              </md-button>
              <md-button class="md-primary" 
                         ng-click="show = !show"
                         ng-show="show">
                         <md-icon md-svg-icon="img/icons/unfold-less.svg"></md-icon>
                         <span>Show Less</span>
              </md-button>
          </md-card-content>
          <md-action-bar layout="row" 
                         layout-align="end center"
                         ng-show="!addRemove">
                         <md-button class="md-fab md-accent fab" 
                                    aria-label="Add To Cart" 
                                    ng-click="addRemove = !addRemove;toggleActive(item)"
                                    ng-class="{active:item.active}">
                                    <md-icon md-svg-src="img/icons/add.svg"></md-icon>
                         </md-button>
        </md-action-bar>
        <md-action-bar layout="row" 
                       layout-align="end center"
                       ng-show="addRemove">
                       <md-button class="md-fab md-accent fab" 
                                  aria-label="Remove From Cart" 
                                  ng-click="addRemove = !addRemove;toggleActive(item)"
                                  ng-class="{active:item.active}">
                                  <md-icon md-svg-src="img/icons/remove.svg"></md-icon>
                       </md-button>
        </md-action-bar>
</md-card>

正在从Parse.com数据库中解析项目

修改

所以我遇到了一些真正的问题所以我在Parse.com上创建了我的对象类,而不是使用工厂初始化它现在正在使用

进行初始化
getOptions(); 

这样可以很好地加载并在不同视图之间保留数据..但是如下所述,我现在有一个问题,即所有ng-repeat创建的child $ scope当然与父$ scope中的值相关联。我在下面给了一个很好的headstart,但仍然无法根据名称或id创建独特的$ scope。我打算开始一个新的帖子,但为了将所有内容保存在一个页面上,我想我只是更新了由于味道的价值已经初始化,我不确定我是否需要在工厂内重新初始化它们。

2 个答案:

答案 0 :(得分:2)

工厂本身可能是单例,这使得它可以跨视图工作,但每次调用时,getFlavours()返回的对象都是列表的新实例 。这就是为什么它似乎没有记录您的更改:它首先执行,但是一旦您尝试再次使用它们,就会使用默认值重置它们。

每次调用给定产品时,都需要确保返回相同的列表实例。

通常,产品分离很简单,因为我们知道每个ng-repeat都有自己的子范围,可以为该产品保存单独的风味实例。但是因为你想要坚持那些需要单件服务的人,你需要在该服务中按产品明确地映射它们。要使用它,您的getFlavors()将需要将产品名称作为参数来唯一标识它。

app.factory('Options', function() {
    // To create a new set of flavors with default settings
    function initFlavors() {
        return [
            { name: 'Vanilla', wanted: false },
            { name: 'Hazelnut', wanted: false },
            { name: 'Almond', wanted: false },
            { name: 'Caramel', wanted: false }
        ];
    }

    var flavorsByProduct = {};

    // Get the flavors for a given product
    flavorsByProduct.getFlavors = function(productName) {
        // On first access for a particular product, create a new set of flavors for it
        if(!flavorsByProduct[productName]) {
            flavorsByProduct[productName] = initFlavors();
        }
        return flavorsByProduct[productName];
    };

    return flavorsByProduct;
});

答案 1 :(得分:0)

你需要改变

$scope.flavors = Options.flavors.getFlavors();代替$scope.flavors = Options.getFlavors();

因为您的工厂仅返回flavors个对象。它不返回getFlavors()函数。