2016-12-14 91 views
1

这是一个骨干教程。下面是代码:什么是“无”功能对集合进行操作?

<!DOCTYPE html> 
<html> 
<head> 
    <meta charset="UTF-8"> 
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 
    <title>To-do App in Backbone.js</title> 

    <!-- ========= --> 
    <!-- CSS --> 
    <!-- ========= --> 
    <style type="text/css"> 
    #todoapp ul { 
     list-style-type: none; /* Hides bullet points from todo list */ 
    } 
    #todo-list input.edit { 
     display: none; /* Hides input box*/ 
    } 
    #todo-list .editing label { 
     display: none; /* Hides label text when .editing*/ 
    } 
    #todo-list .editing input.edit { 
     display: inline; /* Shows input text box when .editing*/ 
    } 
    </style> 
</head> 
<body> 
    <!-- ========= --> 
    <!-- Your HTML --> 
    <!-- ========= --> 

    <section id="todoapp"> 
    <header id="header"> 
     <h1>Todos</h1> 
     <input id="new-todo" placeholder="What needs to be done?" autofocus> 
     <div> 
     <a href="#/">show all</a> | 
     <a href="#/pending">show pending</a> | 
     <a href="#/completed">show completed</a> 
     </div> 
    </header> 
    <section id="main"> 
     <ul id="todo-list"></ul> 
    </section> 
    </section> 
    <div> 
    <p>Find the tutorial and code in <a href="http://adrianmejia.com/blog/2012/09/11/backbone-dot-js-for-absolute-beginners-getting-started/">here</a></p> 
    </div> 

    <!-- Templates --> 
    <script type="text/template" id="item-template"> 
    <div class="view"> 
     <input class="toggle" type="checkbox" <%= completed ? 'checked' : '' %>> 
     <label><%- title %></label> 
     <input class="edit" value="<%- title %>"> 
     <button class="destroy">remove</button> 
    </div> 
    </script> 

    <!-- ========= --> 
    <!-- Libraries --> 
    <!-- ========= --> 
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script> 
    <script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.3.3/underscore-min.js" type="text/javascript"></script> 
    <script src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.2/backbone-min.js" type="text/javascript"></script> 
    <script src="http://cdnjs.cloudflare.com/ajax/libs/backbone-localstorage.js/1.0/backbone.localStorage-min.js" type="text/javascript"></script> 

    <!-- =============== --> 
    <!-- Javascript code --> 
    <!-- =============== --> 
    <script type="text/javascript"> 
    'use strict'; 

    var app = {}; // create namespace for our app 

    //-------------- 
    // Models 
    //-------------- 
    app.Todo = Backbone.Model.extend({ 
     defaults: { 
     title: '', 
     completed: false 
     }, 
     toggle: function(){ 
     this.save({ completed: !this.get('completed')}); 
     } 
    }); 

    //-------------- 
    // Collections 
    //-------------- 
    app.TodoList = Backbone.Collection.extend({ 
     model: app.Todo, 
     localStorage: new Store("backbone-todo"), 
     completed: function() { 
     return this.filter(function(todo) { 
      return todo.get('completed'); 
     }); 
     }, 
     remaining: function() { 
     debugger; 
     return this.without.apply(this, this.completed()); 
     } 
    }); 

    // instance of the Collection 
    app.todoList = new app.TodoList(); 

    //-------------- 
    // Views 
    //-------------- 

    // renders individual todo items list (li) 
    app.TodoView = Backbone.View.extend({ 
     tagName: 'li', 
     template: _.template($('#item-template').html()), 
     render: function(){ 
     this.$el.html(this.template(this.model.toJSON())); 
     this.input = this.$('.edit'); 
     return this; // enable chained calls 
     }, 
     initialize: function(){ 
     this.model.on('change', this.render, this); 
     this.model.on('destroy', this.remove, this); // remove: Convenience Backbone's function for removing the view from the DOM. 
     }, 
     events: { 
     'dblclick label' : 'edit', 
     'keypress .edit' : 'updateOnEnter', 
     'blur .edit' : 'close', 
     'click .toggle': 'toggleCompleted', 
     'click .destroy': 'destroy' 
     }, 
     edit: function(){ 
     this.$el.addClass('editing'); 
     this.input.focus(); 
     }, 
     close: function(){ 
     var value = this.input.val().trim(); 
     if(value) { 
      this.model.save({title: value}); 
     } 
     this.$el.removeClass('editing'); 
     }, 
     updateOnEnter: function(e){ 
     if(e.which == 13){ 
      this.close(); 
     } 
     }, 
     toggleCompleted: function(){ 
     this.model.toggle(); 
     }, 
     destroy: function(){ 
     this.model.destroy(); 
     } 
    }); 

    // renders the full list of todo items calling TodoView for each one. 
    app.AppView = Backbone.View.extend({ 
     el: '#todoapp', 
     initialize: function() { 
     this.input = this.$('#new-todo'); 
     app.todoList.on('add', this.addAll, this); 
     app.todoList.on('reset', this.addAll, this); 
     app.todoList.fetch(); // Loads list from local storage 
     }, 
     events: { 
     'keypress #new-todo': 'createTodoOnEnter' 
     }, 
     createTodoOnEnter: function(e){ 
     if (e.which !== 13 || !this.input.val().trim()) { // ENTER_KEY = 13 
      return; 
     } 
     app.todoList.create(this.newAttributes()); 
     this.input.val(''); // clean input box 
     }, 
     addOne: function(todo){ 
     var view = new app.TodoView({model: todo}); 
     $('#todo-list').append(view.render().el); 
     }, 
     addAll: function(){ 
     this.$('#todo-list').html(''); // clean the todo list 
     // filter todo item list 
     switch(window.filter){ 
      case 'pending': 
      _.each(app.todoList.remaining(), this.addOne); 
      break; 
      case 'completed': 
      _.each(app.todoList.completed(), this.addOne); 
      break; 
      default: 
      app.todoList.each(this.addOne, this); 
      break; 
     } 
     }, 
     newAttributes: function(){ 
     return { 
      title: this.input.val().trim(), 
      completed: false 
     } 
     } 
    }); 

    //-------------- 
    // Routers 
    //-------------- 

    app.Router = Backbone.Router.extend({ 
     routes: { 
     '*filter' : 'setFilter' 
     }, 
     setFilter: function(params) { 
     console.log('app.router.params = ' + params); 
     window.filter = params.trim() || ''; 
     app.todoList.trigger('reset'); 
     } 
    }); 

    //-------------- 
    // Initializers 
    //-------------- 

    app.router = new app.Router(); 
    Backbone.history.start(); 
    app.appView = new app.AppView(); 

    </script> 

</body> 
</html> 

这是什么线做:

remaining: function() { 
     return this.without.apply(this, this.completed()); 
     } 

那是什么做的?

without是从下划线,但是什么是apply从?此外,我把一个调试器在匿名函数内部的那条线上,这是一个错误:

this.apply(this, this.copmleted()); 

为什么没有工作?什么是apply

回答

3

没有

Backbone Collection's underscore methods

Backbone proxies to Underscore.js to provide 46 iteration functions on Backbone.Collection.

this.without相同_.without应用集合本身。

更多detailed answer就此。

应用

apply是从函数的原型功能(在JavaScript规范)。这需要上下文作为第一个参数(在这种情况下为this)以及一个类似数组的对象,用于指定函数应该被调用的参数。

上下文this的值内的函数;它是函数将执行其逻辑的对象。

this.completed()返回一个数组,但this.without需要分别传递每个参数。例如:

this.without(1, 2, 3, 4, 6, 78); 

解开由this.completed()返回到参数列表中的数组,.apply可用于:

this.without.apply(this, [completedModel1, completedModel2, /* etc. */]); 
+0

是适用于此调用个别参数的'without'方法的主要原因?这个''上下文是多余的吗? – Jwan622

+0

@ Jwan622是的,这正是'apply'的用途。你经常会看到使用'apply'来使用数组作为函数参数的技巧。 'this'看起来多余,但'apply'覆盖上下文,所以如果你传递'null'作为上下文,'this'不会是集合。 –

相关问题