如何从共享工厂绑定数组或对象?

时间:2014-08-28 12:24:33

标签: javascript arrays angularjs

我有一个名为Model的Angular工厂,它在多个控制器之间共享。 基本上这个Model封装了属性和帮助方法。

我现在正在尝试将此模型与我的视图绑定,并且我有一个奇怪的行为,Model的嵌套对象和对象数组未正确绑定。

我认为这个问题是由于我试图通过引用修改其他对象内的对象这一事实引起的。也许我已经失去了嵌套元素的上下文?

我该如何解决这个问题?

这是我的应用:

var app = angular.module('plunker', []);

app.factory('Blog', function() {
  function Blog(id) {
    this.load(id);
  }

  Blog.prototype = {
    name: "",
    description: [{
      value: ""
    }, {
      value: ""
    }, {
      value: ""
    }],
    website: {
      name: "",
      url: ""
    },
    load: function(id) {

    },
    helper1: function() {
      // implementation
    },
    helper2: function() {
      // implementation
    }
    // many other helpers...
  }
  return Blog;
});

app.controller('MainCtrl', function($scope, Blog) {
  $scope.model = new Blog(12);
});

最后我的观点

<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="angular.js@1.2.x" src="https://code.angularjs.org/1.2.22/angular.js" data-semver="1.2.22"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <p>Name <input ng-model="model.name"></p>
    <div ng-repeat="line in model.description">
      Description line {{$index}} <input ng-model="line.value">
    </div>
    <p>Website name <input ng-model="model.website.name"></p>
    <p>Website url <input ng-model="model.website.url"></p>
    <p>Result : {{ model | json  }}</p>
  </body>

</html>

为了说明问题,我创建了一个plunker example 在输入字段中输入值时,Model不会随更改一起更新。仅更新字段name

提前致谢

2 个答案:

答案 0 :(得分:1)

这里的博客是应该由工厂创建的服务。您的工厂应该返回新实例/值/或函数。

您没有创建注入您控制器的博客实例,注入的内容应该是唯一可用于注入其他内容的实例。

因此,服务是单身(由工厂创建)。

答案 1 :(得分:1)

服务由Angular实例化,然后在需要的地方注入它们的引用。 只需按以下方式更改代码

即可
var app = angular.module('plunker', []);

app.factory('Blog', function() {

  return {
    name: "",
    description: [
            {value: ""},
            {value: ""},
            {value: ""}
        ],
    website: {
      name: "",
      url: ""
    },
    helper1: function() {
      // implementation
    },
    helper2: function() {
      // implementation
    }
    // many other helpers...
  }
  //return new Blog(); 
});  

app.controller('MainCtrl', function($scope, Blog) { 
  $scope.model = Blog;
});

服务,工厂和提供商的工作方式略有不同。我希望你明白其他明智的读这篇优秀的文章

http://tylermcginnis.com/angularjs-factory-vs-service-vs-provider/

NEW plunkr

http://plnkr.co/edit/FGOcPWVMeFDSyVtmv8Xd?p=preview

工厂公开了一种新方法,您可以使用该方法创建Blog的新实例。

我认为这也是因为实现了JSON过滤器,您无法看到所有值。 因为描述和网站和网址都是对象的原型,所以它不会显示它。

我添加了一个用于记录模型的按钮,您可以在控制台中看到值已更改

修改2

问:我不明白为什么JSON过滤器没有显示值?

答:我认为可能是它的实施方式,可能是它的重量轻。否则它必须遍历它的整个原型链

问:由于Blog的性质,为何将值放入 proto

答:这是因为你在Blog的原型中添加了值,而不是在Blog本身中。这就是原型继承在javascript中的工作原理。当您必须创建1000个博客实例时,优势就在于此。现在每个实例可以具有相同的方法和属性,或者使其重量轻,每个实例可以共享其原型中的同一个对象。(想想OO语言中的基类) 阅读本文以获得更清晰

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain