以角度更新子节点的父范围

时间:2015-01-07 17:44:19

标签: javascript angularjs cordova ionic-framework cordova-plugins

我真的很擅长这一切,但我正在创建一个小应用程序,我可以添加带有细节的项目,并使用离子,cordova和angularjs更新它们等,我正在努力应对以下场景:

我将离子视图设置如下:

的index.html:

<div ng-controller="mainController">
  <ion-nav-view>

  </ion-nav-view>
</div>

list.html:

<ion-content>
    <ion-list>
        <ion-item ng-repeat="item in items track by $index | filter:search" ui-sref="detailView({itemId: $index})">{{ item.name }}</ion-item>
    </ion-list>
</ion-content>

add.html:

<ion-content>
    <label class="item item-input">
        <input type="text" ng-model="item.name" placeholder="Item title..."/>
    </label>
    <label class="item item-input">
        <textarea cols="30" rows="10" ng-model="item.field1" placeholder="Field1..."></textarea>
    </label>
    <label class="item item-input">
        <textarea cols="30" rows="10" ng-model="item.field2" placeholder="Field2..."></textarea>
    </label>
    <div class="row">
    <div class="col col-33"></div>
    <div class="col col-33">
        <button class="button button-block" ng-click="addItem()">Add</button>
    </div>
    <div class="col col-33"></div>
    </div>
</ion-content>

然后我做了一个我正在测试的工厂,它看起来像这样:

工厂:

.factory('itemFactory', ['$cordovaFile', '$q', function ($cordovaFile, $q) {
var itemFactory = {};

itemFactory.get = function () {
  var deferred = $q.defer();

  $cordovaFile.checkFile('items.json')
    .then(function (result) {

      $cordovaFile.readAsText('items.json')
        .then(function (result) {
          var parsedResult = JSON.parse(result);
          deferred.resolve(parsedResult)
        }, function (err) {
          deferred.resolve([]);
        })

    }, function (err) {

      switch(err.code) {
        case 1:
          $cordovaFile.createFile('items.json');
          deferred.resolve([]);
      }

    });

  return deferred.promise;
};

itemFactory.add = function (itemsFromScope, newItem) {
  var deferred = $q.defer(),
    dataToWrite;
  itemsFromScope.push(newItem);

  dataToWrite = JSON.stringify(itemsFromScope);

  $cordovaFile.writeFile('items.json', dataToWrite, {append: false})
    .then(function (result) {
      deferred.resolve(itemsFromScope);
    },function (err) {
      console.log("Write failed");
      deferred.reject(err);
    });

  return deferred.promise;
};

return itemFactory;

  }]);

然后是mainController:

  .controller('mainController', function ($scope, itemFactory) {
    $scope.items = [];
    itemFactory.get()
      .then(function (result) {
        $scope.items = result;
      });
  })

然后是addController:

  .controller('addController', function ($scope, $location, itemFactory) {
    $scope.newItem = {};

    $scope.newItem.name = "";
    $scope.newItem.field1 = "";
    $scope.newItem.field2 = "";


    $scope.addItem = function () {

      itemFactory.add($scope.items, $scope.newItem)
        .then(function (result) {
          $scope.items = result;
        });

      $scope.title="";
      $scope.field1="";
      $scope.field2="";

      $location.path('/').replace();
    };

    $scope.goBack = function () {
      $scope.title="";
      $scope.field1="";
      $scope.field2="";
      $location.path('/').replace()
    };


  })

使用ui-router将控制器加载到视图中。

现在这一切都很好,它可能不是最好的东西,但是,嘿,我只是在尝试。但是当我注意到在我的addController中我有$scope.field1="";等而不是$scope.newItem.field1 = "";时,奇怪的部分开始了。所以我决定修复它们,在修复之后,添加不再起作用了。我没有在mainController中的$ scope.items中添加正确的值,而是在其上获取空项。当我在iOS模拟器上运行时,我的列表中添加了一个空行。如果我重新启动模拟器,新项目就会显示正常。我假设某些东西现在在错误的时间或某些东西刷新,但我无法弄清楚什么和在哪里。任何提示或解释?

编辑:添加了一个JS小提琴相同的问题以简化:http://jsfiddle.net/9gx3tfmy/ 如您所见,数据已在工厂中添加到阵列中,但ui未更新

EDIT2:实际上,nvm,适用于jsfiddle,但与ionic和它的视图完全相同的东西是行不通的。我删除了代码的$ cordovaFile部分,但同样的事情,即使在浏览器上也是如此。我将检查是否可以将jsfiddle更新为类似的状态

EDIT3:现在我设法让它在jsfiddle中运行,但是不能在我的项目中尝试它,直到今天晚些时候。在这里工作小提琴:http://jsfiddle.net/9yhryL6y/8/

如果我没有将$ scope.newItem = {}添加到a​​ddController,那么这些项目将被添加为undefined。

2 个答案:

答案 0 :(得分:0)

看起来您的输入字段已绑定到add.html中的$scope.item,而不是newItem,因此当您尝试添加$scope.newItem时,<label class="item item-input"> <input type="text" ng-model="newItem.name" placeholder="Item title..."/> </label> <label class="item item-input"> <textarea cols="30" rows="10" ng-model="newItem.field1" placeholder="Field1..."></textarea> </label> <label class="item item-input"> <textarea cols="30" rows="10" ng-model="newItem.field2" placeholder="Field2..."></textarea> </label> 可能仍然是默认的空项。

尝试:

items

JSFiddle工作原因也是因为你正在添加&#34; value1&#34;等字符串。到name数组,但它期望一个具有items属性的对象。

另一件需要注意的事情就是将范围变量推入{{1}}数组,因为它没有创建新对象,只是将输入绑定到模型中的模型推送到数组中。示例:http://jsfiddle.net/9yhryL6y/

离子ToDo列表演示可能对将新对象推入数组进行ng-repeat的示例很有用。 https://github.com/driftyco/ionic-todo/blob/master/www/js/app.js

答案 1 :(得分:0)

所以我终于弄明白了。我的问题是我用Angular误解的两件事。我从工厂返回了一个完整的对象,并将其中的一部分直接绑定到范围内,如下所示:

.controller('myController', ['$scope', 'myFactory', function ($scope, myFactory) {
  $scope.items = myFactory.items;
})])
.factory('myFactory', function () {
  var factoryItems = {};

  factoryItems.items = ['item1', 'item2'];
});

现在当我更新我的工厂中的数组时,它没有在范围内更新。所以改变了对它的绑定:

$scope.myFactory = myFactory;

然后在工厂中使用的视图如下:

ng-repeat="item in myFactory.items track by $index"

这解决了这个问题。这篇文章给了我很多帮助:

Modified data in a factory that's bound to a controller's scope, it doesn't update