0

Допустим, у меня есть JSON как это:визуализации Вид Backbone модели возвращает неопределенное значение

JSON пример, мой JSON проверяется на jsonlint и она работает.

json_object = { 
"texts_model": { 
"hello": "hola", 
"icon_text": "Icon!" 
}, 
"collection_vias": { 
"text": "hola", 
"icon_text": "Icon!" 
} 
}; 

Я сделал коллекцию, анализирующую содержимое JSON и формирует модель и коллекцию из этого JSON.

App.TemplatesCollection = Backbone.Model.extend({ 

    model: App.TemplateModel, 
    url: TEMPLATES_SERVICE, 

    initialize: function(){ 
     this.fetch({ 
      success: (function() { 
       console.log(' Success '); 
      }), 
      error:(function (e) { 
       //console.log(' Error: ' + e); 
      }), 
      complete:(function (e) { 
       console.log(' Fetch completado con exito. '); 

      }) 
     }); 
    }, 

    //Here i generate all my models and collections. 
    parse: function(response){ 

     App.texts = new App.TemplateModel(response.text_model); 
     App.vias = new App.ViasCollection(response.collection_vias); 
     return response; 
    }, 

    //I was trying with the get function but i the only thing i got was undefined. 
    plain_texts: function(){ 
     return(this.get('plain_texts')) ; 
    } 

}); 

И вид, как это:

App.TemplateView = Backbone.View.extend ({ эш:. App $ main_content, инициализации: функция() { _.bindAll (это , 'render'); }, // Здесь я передаю шаблон (html source), который я хочу отобразить. render: function (template) { var html = render (template, this.model.toJSON()) ; Приложение. $ Main_content.html (html); return this; } });

И мой start.js где они живут все заявления моих моделей и представлений:

// приложение App = {

init: function(){ 
    console.log('Iniciando...'); 

    //variables y constantes 
    App.$main_content  = $('#main-content-content'); 
    App.$main_header  = $('#main-header-content') 
    App.$main_navigation = $('#main-navigation-content'); 

    //data 
    App.templates = new App.TemplatesCollection(); 

    //views 
    App.templateView = new App.TemplateView({model: App.texts}); 

    //router 
    App.router = new App.Router(); 


}, 

start: function(){ 
    //init 
    App.init(); 

    //router 
    Backbone.history.start(); 

} 

}

И маршрутизатор:

// router App.Router = Backbone.Router.extend ({

routes:{ 
    "" : "index", 
    ":web" : "url" 

}, 

index: function(){ 
    console.log("index"); 

    //Here i do not know what to do, i mean do i have to instiate the View each time i go to index? or only render? 
    App.templateView = new App.TemplateView({model: App.texts}); 
    App.templateView.render("sections/login/form"); 
}, 

url: function(web){ 
    console.log(web); 
} 

});

//on document ready 
$(function(){ 

    App.start(); 


}); 

Моя проблема заключается в том, что когда HTML загружается единственное, что я имею: «Uncaught TypeError: Невозможно вызвать метод„toJSON“неопределенных»

Но когда я положил это на консоли разработчика :

App.templateView = new App.TemplateView({model: App.texts}); 
App.templateView.render("sections/login/form"); 

Мой взгляд обрабатывается правильно.

Почему мой взгляд не отображается на загрузке и только когда я помещаю свой код в консоль разработчика?

Как я могу отобразить свою модель на представлении на URL-адресе маршрутизатора? Почему я не определился с html, загруженным на консоль разработчика?

---- EDIT ---

Хорошо,

Я думаю, что я понимаю. Возможно, я создаю проблему, которая не должна иметь проблемы.

Теперь моя модель выглядит так:

App.TemplatesCollection = Backbone.Model.extend({ 

    model: App.TemplateModel, 
    url: TEMPLATES_SERVICE, 

    plain_texts: function(){ 
     return this.get('texts') ; 
    }, 
    initialize: function(){ 
     this.fetch(); 
    } 

}); 

А Вид:

App.TemplateView = Backbone.View.extend({ 
    el: App.$main_content, 
    initialize: function(){ 

     console.log(this.collection); 
     var ea = this.collection.get('texts'); 
     console.log(ea); 
    }, 
    render: function(template){ 
     console.log(this.collection); 
     return this; 
    } 
}); 

Теперь я вижу свою коллекцию в моем View.

Но когда я пытаюсь сделать это, чтобы получить только текстовую версию на мой взгляд:

var ea = this.collection.get('texts'); 
    console.log(ea); 

Im получая ошибку неопределенными:

Uncaught TypeError: Cannot call method 'get' of undefined

Любая идея о том, как я могу решить эту проблему ?

Я пытаюсь решить это самостоятельно. Я не хочу выглядеть так, как будто я хочу разработать свое решение.

Заранее спасибо.

ответ

0

Немного трудно прочитать, но с быстрым взглядом: ваш App.texts = находится в функции parse() вашей коллекции. В результате он вызывается после того, как .fetch() в коллекции выполняется ... до тех пор, ваши App.texts не определены!

Если App.texts не задан при создании TemplateView, то модель представления на самом деле будет неопределенной, и поэтому в рендере, когда используемый вами движок шаблона делает toJSON(), он скажет, что он имеет неопределенное значение ...

Возможно, возникнут другие проблемы, но этот вопрос наиболее вопиющий. Вот быстро & грязное исправление: как только функция fetch() будет выполнена, ваша коллекция вызовет событие сброса. Это ваш реплик для выполнения рендеринга. Итак, что вы можете сделать, вместо передачи модели на вид, вы можете передать коллекцию вместо:

App.templateView = new App.TemplateView({collection: App.templates}); 

Теперь, на ваш взгляд инициализируем, вы можете сделать что-то вроде:

if(App.texts) { 
    //Your collection has already fetched and already went through parse() 
    this.model = App.texts; 
    this.render("sections/login/form"); 
} else { 
    //Your collection hasn't done the fetch yet 
    view = this; 
    this.collection.one("reset", function(){ 
    view.model = App.texts; 
    view.render("sections/login/form"); 
    }); 
} 

Если вы дадите коллекцию как параметр для конструкции View, она будет сохранена в this.collection, как и в случае с моделью. Идея здесь заключается в том, чтобы использовать события, чтобы знать, когда делать рендеринг, а также дать представление, когда оно будет готово к рендерингу. Вы также можете сделать что-то в своей функции render(), чтобы проверить, определена ли модель!

Чтобы проверить, подходит ли этот анализ, вы можете добавить console.log (App.texts); в вашей индексной функции в маршрутизаторе.

Одним из способов сделать код более очевидным является инициализация App.texts и App.vias непосредственно в init вашего приложения. И дайте ссылку на них на ваш AppTemplatesCollection, если вам действительно необходимо загрузить их в синтаксический анализ AppetchFetch(). Разница заключается в том, что вы можете привязываться к событиям из коллекции App.vias ('add', 'remove', 'reset') или к модели App.texts ('change').

Еще одна вещь, которую я заметил, это то, что у вас есть коллекция App.TemplateModel, но вы все еще создаете App.texts, где вы поместите результат извлечения в свой собственный экземпляр App.TemplateModel?Это не кажется правильным, может быть, у вас есть причина для этого, но в самом общем случае коллекция, как предполагается, должна обрабатывать создание моделей, особенно после извлечения!

Обычный метод использования метода parse() - это данные с боковой загрузкой (другие модели/коллекции), изменение формата (от XML до чего-то, что может понять JS) или удаление ненужных ключей (например, user: { id: ..., name: ...}, вы вернете response.user, чтобы Backbone мог играть с правильным хешем напрямую). То, что вы здесь делаете, похоже, выпадает из этого шаблона, так что, может быть, это причина для беспокойства?

+0

Чтобы уточнить, вы открыли мне глаза. Я делал все неправильно. Я удалил выборку из Модели и коллекции, и когда я вызываю рендер, я пытаюсь получить собранную коллекцию и в успешном событии я визуализирую свое представление. Спасибо. – DiegoKTC

0

В своем коде вы создали collection как:

App.TemplatesCollection = Backbone.Model.extend({ 
//rest of the code 

Если вы хотите создать collection вам нужно расширить Backbone.Collection и не Backbone.Model.

App.TemplatesCollection = Backbone.Collection.extend({ 
//rest of the code 
+0

Спасибо, я просто реорганизовал свой код. Я ошибался во многих вещах. Стойка трудно учиться в начале. Спасибо. – DiegoKTC

+0

Это не так сложно. Возможно, было бы неплохо начать с (http://addyosmani.github.io/backbone-fundamentals/) –

Смежные вопросы