【问题标题】:Two way binding issue for Angular book app exampleAngular 图书应用示例的两种方式绑定问题
【发布时间】:2015-02-22 01:14:30
【问题描述】:

我是一个 Angular 菜鸟,试图通过我在这里和那里找到的一些示例来工作。我在这里找到了一个有趣的例子:http://kirkbushell.me/when-to-use-directives-controllers-or-services-in-angular/,我试图实际运行它。在大多数情况下,它按我的预期工作。

该服务肯定会按预期存储书籍并添加新书籍,但是视图 (DOM) 中输出的书籍列表没有更新。似乎没有正确设置双向绑定。我可能做错了什么?

这是(大部分)有效的代码:

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

module.service('Book', ['$rootScope', 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);
      $rootScope.$broadcast('books.updated');
    }
  };

  return service;
}]);


// Ctrl fn
var ctrl = ['$scope', 'Book', function($scope, Book) {
  $scope.$on('books.updated', function(event) {
    console.log(Book.books);
    $scope.books = Book.books;
  });

  $scope.books = Book.books;
}];
// Initialize the controller
module.controller('books.list', ctrl);


// Directive to handle add book button
module.directive('addBookButton', ['Book', function(Book) {
  return {
    restrict: 'A',
    link: function(scope, element, attrs) {
      element.bind('click', function() {
        Book.addBook({title: 'Star Wars', author: 'George Lucas'});
      });
    }
  };
}]);
<!DOCTYPE html>
<html>
  <head>
    <title>Book example</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.min.js"></script>
    <script src="script.js"></script>
  </head>
  <body ng-app="bookModule">
    <h4>Book list</h4>
    <ul ng-controller="books.list">
      <li ng-repeat="book in books">
        Title: {{book.title}} | Author: {{book.author}}
      </li>
    </ul>
    <button add-book-button>Add book</button>
  </body>
</html>

感谢您的意见!

【问题讨论】:

    标签: javascript angularjs javascript-databinding


    【解决方案1】:

    您的点击事件是手动绑定的,并且您没有使用角度点击指令,这意味着您需要使用 scope.$apply() 手动运行摘要循环。

     element.bind('click', function() {
        Book.addBook({title: 'Star Wars', author: 'George Lucas'});
        scope.$apply();
      });
    

    var module = angular.module('bookModule', []);
    
    module.service('Book', ['$rootScope', 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);
          $rootScope.$broadcast('books.updated');
        }
      };
    
      return service;
    }]);
    
    
    // Ctrl fn
    var ctrl = ['$scope', 'Book', function($scope, Book) {
      $scope.$on('books.updated', function(event) {
        console.log(Book.books);
        $scope.books = Book.books;
      });
    
      $scope.books = Book.books;
    }];
    // Initialize the controller
    module.controller('books.list', ctrl);
    
    
    // Directive to handle add book button
    module.directive('addBookButton', ['Book', function(Book) {
      return {
        restrict: 'A',
        link: function(scope, element, attrs) {
          element.bind('click', function() {
            Book.addBook({title: 'Star Wars', author: 'George Lucas'});
            scope.$apply();
          });
        }
      };
    }]);
    <!DOCTYPE html>
    <html>
      <head>
        <title>Book example</title>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.min.js"></script>
        <script src="script.js"></script>
      </head>
      <body ng-app="bookModule">
        <h4>Book list</h4>
        <ul ng-controller="books.list">
          <li ng-repeat="book in books">
            Title: {{book.title}} | Author: {{book.author}}
          </li>
        </ul>
        <button add-book-button>Add book</button>
      </body>
    </html>

    【讨论】:

    • 补充一点,最好只使用 Angular 的 ng-click,而不是为这样的事情编写自己的指令。只需在控制器范围(例如 $scope.addBook)上定义点击处理程序并将其连接到 ng-click(例如 ng-click="addBook()")。 ng-click 绑定到一个 Angular 表达式,可以在类似于 vanilla JS 中的 eval 的范围内安全地对其进行评估(但安全),可以在此处找到更多信息:docs.angularjs.org/api/ng/directive/ngClick
    • 有效!我在 Angular 开发人员指南中也读到过一段时间......我只是没有意识到这是我需要使用它的情况。谢谢你的解释!
    • @DerekWebb 事情是我知道你可能是出于实验目的,但是有一个指令来绑定一个点击事件可能没有多大意义。作为一个例子你的指令可以有一个模板说&lt;button ng-click="addBook()"&gt;Add Book&lt;/button&gt;,只需将指令设置为``。你应该尽量避免使用 scope.$apply ,但当然有很多情况下你会需要它,但我建议你在使用时有意识.. :)
    • 好的,我也会试试 ng-click 指令。再次感谢。
    猜你喜欢
    • 2019-02-27
    • 1970-01-01
    • 2018-10-26
    • 1970-01-01
    • 1970-01-01
    • 2020-04-07
    • 1970-01-01
    • 1970-01-01
    • 2016-10-19
    相关资源
    最近更新 更多