2016-12-17 5 views
0

Мое приложение разработало, что маршрутизатор изменен, а затем отображает другой вид , но я не знаю, как связь для созданного другого объекта представления.Как установить другие объекты вида в backbone.js

router.js

var app = app || {}; 
(function() { 
    'use strict'; 
    var views = app.view = app.view || {}; 
    app.Router = Backbone.Router.extend({ 
     routes: { 
      '*home': 'homeRoute', 
      'about': 'aboutRoute', 
      'contact': 'contactRoute' 
     }, 
     initialize: function() { 
      // create the layout once here 
      this.layout = new views.Application({ 
       el: 'body', 
      }); 
     }, 
     homeRoute: function() { 
      var view = new views.Home(); 
      this.layout.setContent(view); 
     }, 
     aboutRoute: function() { 
      var view = new views.About(); 
      this.layout.setContent(view); 
     }, 
     contactRoute: function() { 
      var view = new views.Contact(); 
      this.layout.setContent(view); 
     } 
    }); 
})(); 

view.js

var app = app || {}; 
(function() { 
    'use strict'; 
    //views linitalize 
    var views = app.view = app.view || {}; 
    views.Application = Backbone.View.extend({ 
     initialize: function() { 
      // caching the jQuery object on init 
      this.$content = this.$('#content'); 
      this.$loading = this.$('#loading'); 
     }, 
     setContent: function(view) { 
      var content = this.content; 
      if (content) content.remove(); 
      this.showSpinner(); 
      content = this.content = view; 
      console.log(view); 
      //content rednering 
      this.$content.html(content.render().el, this.hideSpinner()); 
     }, 
     showSpinner: function() { 
      this.$loading.show(); 
     }, 
     hideSpinner: function() { 
      this.$loading.hide(); 
     }, 
    }); 
    views.Home = Backbone.View.extend({ }); 
    views.About = Backbone.View.extend({ 
     initialize: function(){ 
     this.render(); 
     }, 
     render: function(){ 
     var template = _.template("<strong>About page</strong>"); 
     } 
    }); 
    views.Contact = Backbone.View.extend({ 
     my_template: _.template("<strong>Contact page</strong>"); 
    }); 
})(); 

index.html

<!DOCTYPE html> 
<html> 
    <head> 
    <meta charset="utf-8"> 
    <title></title> 
    </head> 
    <body> 
    <ul class="pills"> 
     <li><a href="#/">Home</a></li> 
     <li><a href="#/about">About</a></li> 
     <li><a href="#/contact">Contact</a></li> 
    </ul> 
    <div id="content"></div> 
    <div id="loading">load the page...</div> 
    <div id="sumMenu"></div> 
    <script src="lib/jquery-3.1.1.min.js"></script> 
    <script src="lib/underscore.js"></script> 
    <script src="lib/backbone.js"></script> 
    <script src="lib/backbone.localstorage.js"></script> 
    <script src="routers/router.js" ></script> 
    <script src="views/view.js" ></script> 
    <script src="views/app.js" ></script> 
    </body> 
</html> 

Если вы посмотрите на этот код, вы будетеПонимаю. Трудно сообщить, что я сказал выше.

Посмотрите на view.js, я написал 3 просмотры свойство (home, about, contact) и те, которые содержатся код, который не запускается.

my_template: _.template("<strong>Contact page</strong>"); 

Я действительно хочу знать, что после создания объекта, как установить значение и рендеринг объектов?

ответ

2

Код сильно вдохновлен my other answer, но вы должны читать Backbone documentation (а также Underscore's), чтобы понять, что происходит, что вы делаете, и что нужно сделать, чтобы добавить функции к нему. В противном случае вы всегда будете отходить от рабочего кода в новый беспорядок, который вы не понимаете.

Документ Backbone короткий и сладкий, а source code заполнен комментариями. Не читайте все документы Underscore, но прочитайте, по крайней мере, документацию для функций, которые вы используете (например, _.template).


Router routes

Поскольку вы копировать-вставить точный код из другого ответа без предварительной проверки, если она работает, вы скопировали ошибку, которую я сделал. В первую очередь следует определить более конкретные маршруты, а последний маршрут - последний.

routes: { 
    'about': 'aboutRoute', 
    'contact': 'contactRoute', 
    // put the catch-all last 
    '*home': 'homeRoute', 
}, 

При вызове нового маршрутизатора, его конструктор вызывает _bindRoutes который разбирает маршруты из последних к первому.

_bindRoutes: function() { 
    if (!this.routes) return; 
    this.routes = _.result(this, 'routes'); 
    var route, routes = _.keys(this.routes); 
    while ((route = routes.pop()) != null) { 
    this.route(route, this.routes[route]); 
    } 
}, 

Маршруты добавлены позже могут переопределить заявленные ранее маршруты.


render function

Как вы думаете, следующий будет делать?

render: function(){ 
    var template = _.template("<strong>About page</strong>"); 
} 

Так что все, что делает сейчас:

  • создает новую функцию,
  • помещает его в локальной переменной с именем template
  • и не делать ничего другого.

или даже это:

my_template: _.template("<strong>Contact page</strong>"); 

my_template собственности на представлениях не является стандартным Магистральная, так что если вы ничего не делаете с ним, он не будет делать что-то само по себе.

Чтобы понять, что вам нужно знать, что _.template функции Подчеркивания принимает шаблон строку в качестве аргумента (и, при необходимости объекта установок) и возвращает новую скомпилированную функцию шаблона, который принимает объект в качестве аргумента. (More info and examples)

Backbone view's render Функция предоставляется разработчику для переопределения. Это должно идеально что-то сделать и быть idempotent.

Простой взгляд может быть:

views.About = Backbone.View.extend({ 
    template: _.template("<strong>About page</strong>"), 
    render: function() { 
     this.$el.html(this.template()); 
     return this; 
    } 
}); 

Хорошая конвенция является return this в конце render, чтобы позволить прикованных вызовы.

И вы должны делать это, потому что вы цепочки вызовов в коде:

content.render().el 

JQuery и el

Почему вы проходите this.hideSpinner()?

this.$content.html(content.render().el, this.hideSpinner()); 

В то время как это сделать изменения HTML в #content DIV с режимом представления el, используя this.hideSpinner() возвращаемого значения в качестве второго параметр не имеет смысла.

jQuery's .html function принимает только один параметр.


Куда поместить погрузчик?

Не в пределах синхронной манипуляции с DOM. Бесполезно ставить прядильщик, который перед тем, как его увидеть, удаляется.

Погрузчик с обратной связью имеет смысл, когда имеется асинхронная загрузка, и что вы хотите сообщить пользователю, что страница не разбилась или не замерла.

Скажите, что вы хотите загружать новости для главной страницы.

homeRoute: function() { 
    console.log("showing the spinner"); 
    this.layout.showSpinner(); 

    var collection = new Backbone.Collection({ 
      url: "/you/api/url/for/latest/news" // simple example 
     }), 
     view = new views.Home({ 
      collection: collection 
     }); 

    collection.fetch({ 
     context: this, 
     success: function() { 
      console.log("removing the spinner"); 
      this.layout.hideSpinner(); 
      this.layout.setContent(view); 
     } 
    }); 

    console.log("End of homeRoute function"); 
}, 

В консоли вы увидите журналы в следующем порядке:

showing the spinner 
End of homeRoute function 
removing the spinner 

Более подробную информацию см:

+0

Спасибо сэр. ваш очень добрый :) У меня есть еще вопрос, что над вашим ответом я пишу ** _ bindRoutes **, тогда вызов конструкции автозагрузка его? а также визуализировать ** вернуть это; ** тоже? –

+0

@SeanSin '_bindRoutes' - это« частная »функция маршрутизатора Backbone's. Он вызывается в любом конструкторе маршрутизатора. Я включил его в свой ответ в качестве ссылки. 'return this' в render является соглашением, я цитировал документацию по этому вопросу. По умолчанию ['render'] (https://github.com/jashkenas/backbone/blob/7da4ed73e7402baf614a50a6551d47ace68b5239/backbone.js#L1348-L1353) делает это по умолчанию и позволяет цепочки вызовов функций. –