2012-06-27 4 views
1

У меня простая, но запутанная проблема. У меня есть следующий фрагмент кода:Модель мачты отсутствует, но я не понимаю, почему

<div id="restaurant_locations"></div> 

<script type="text/javascript"> 
    $(function() { 
    window.router = new Lunchhub.Routers.RestaurantLocationsRouter({ 
     restaurantLocations: <%= @restaurant_locations.to_json.html_safe -%> 
    }); 
    Backbone.history.start({pushState: true}); 
    }); 
</script> 

, который выдает эту ошибку:

Uncaught TypeError: Cannot call method 'toJSON' of undefined 

Если я вынуть {pushState: true} часть, хотя, и просто делать Backbone.history.start() без аргументов, она работает просто отлично.

Рядом с ошибкой говорится: show_view.js: 19. Вот что эта часть show_view.js выглядит следующим образом:

ShowView.prototype.template = JST["backbone/templates/restaurant_locations/show"]; 

    ShowView.prototype.render = function() { 
     $(this.el).html(this.template(this.model.toJSON())); // LINE 19 
     Uncaught TypeError: Cannot call method 'toJSON' of undefined 
     return this; 
    } 

Так что я думаю this.model не определено. Вот show_view CoffeeScript:

Lunchhub.Views.RestaurantLocations ||= {} 

class Lunchhub.Views.RestaurantLocations.ShowView extends Backbone.View 
    template: JST["backbone/templates/restaurant_locations/show"] 

    render: -> 
    $(@el).html(@template(@model.toJSON())) 
    return this 

Если я могу сделать @model быть то, что она должна быть, я предполагаю, что это могло бы решить эту проблему. Но я не знаю, откуда приходит @model или что-то еще.

Что мне нужно сделать?

Редактировать: Я получил немного дальше. В функции show ниже id настроен на «restaurant_locations», и, конечно, нет члена @restaurantLocations с идентификатором restuarant_locations. Тот факт, что id установлен в restaurant_locations, делает определенное чувство; URL-адрес, который я делаю, - http://localhost:3000/restaurant_locations. Но похоже, что нужно называть функцию index, а не show, если это URL, к которому я иду.

class Lunchhub.Routers.RestaurantLocationsRouter extends Backbone.Router 
    initialize: (options) -> 
    @restaurantLocations = new Lunchhub.Collections.RestaurantLocationsCollection() 
    @restaurantLocations.reset options.restaurantLocations 

    routes: 
    "new"  : "newRestaurantLocation" 
    "index" : "index" 
    ":id/edit" : "edit" 
    ":id"  : "show" 
    ".*"  : "index" 

    newRestaurantLocation: -> 
    @view = new Lunchhub.Views.RestaurantLocations.NewView(collection: @restaurantLocations) 
    $("#restaurant_locations").html(@view.render().el) 

    index: -> 
    @view = new Lunchhub.Views.RestaurantLocations.IndexView(restaurantLocations: @restaurantLocations) 
    $("#restaurant_locations").html(@view.render().el) 

    show: (id) -> 
    restaurant_location = @restaurantLocations.get(id) 

    @view = new Lunchhub.Views.RestaurantLocations.ShowView(model: restaurant_location) 
    $("#restaurant_locations").html(@view.render().el) 

    edit: (id) ->     
    restaurant_location = @restaurantLocations.get(id) 

    @view = new Lunchhub.Views.RestaurantLocations.EditView(model: restaurant_location) 
    $("#restaurant_locations").html(@view.render().el) 
+0

'showVideo.model' происходит от' нового ShowView ({model: myModelInstance}) '. Извините, но я должен сказать, что если вы не знаете, что вам следует начать расследование с помощью Backbone в гораздо более простых сценариях. – fguillen

+0

Вы копировали pasta? – jakee

+0

Возможно, я должен был упомянуть: я на Rails и использую жемчужину «backbone-rails», которая автоматически генерирует много кода. Я бы ожидал, что он будет работать без меня, чтобы отлаживать его сгенерированный код, но это не так. –

ответ

0

id is set to "restaurant_locations" , and there's of course no member of @restaurantLocations with an id of "restuarant_locations" .

Похоже, у вас есть проблема маршрутизации так что давайте посмотрим на ваши маршруты:

routes: 
    "new"  : "newRestaurantLocation" 
    "index" : "index" 
    ":id/edit" : "edit" 
    ":id"  : "show" 
    ".*"  : "index" 

Я вижу несколько проблем там. Прежде всего, маршруты не являются регулярными выражениями, поэтому ".*" не соответствует тому, что делает /.*/ (т. Е. Любая последовательность символов), оно фактически соответствует любому количеству периодов (т. Е. /^.*$/); вы можете запустить его через _routeToRegex самостоятельно, чтобы увидеть, что происходит с '.*':

var namedParam = /:\w+/g; 
var splatParam = /\*\w+/g; 
var escapeRegExp = /[-[\]{}()+?.,\\^$|#\s]/g; 
//... 
_routeToRegExp: function(route) { 
    route = route.replace(escapeRegExp, '\\$&') 
       .replace(namedParam, '([^\/]+)') 
       .replace(splatParam, '(.*?)'); 
    return new RegExp('^' + route + '$'); 
}, 

Следующая проблема заключается в том, что ":id" соответствует почти ничего. routeToRegexp конвертирует ":id" в /^([^/]+)$/; что регулярное выражение соответствует любой непустой последовательности без косой черты и, в частности, соответствует тому, что соответствует большинству ваших других маршрутов.

Так что, когда вы ожидаете, чтобы ударить '.*': 'index' от /restaurant_locations, вы на самом деле удары ':id': 'show' и вы получаете повезло, что '/new' и '/index' не также получать подкреплены ':id'. Имейте в виду, что порядок элементов в объекте Script (Java | Coffee) является реализацией, поэтому порядок, в котором они появляются в исходном коде, действительно не имеет значения; многие реализации JavaScript будут уважать исходный порядок, но никогда не будут зависеть от него.

Поскольку заказ на маршрут не имеет значения, вы должны посмотреть на свои ключи routes как простой неупорядоченный набор, и вы - человек - должны убедиться, что ваши шаблоны маршрутов действительно соответствуют определенным вещам. Если вам нужно накладывать шаблоны маршрутов, и вам нужно, чтобы они соответствовали определенному порядку, вы можете использовать метод route в вашем маршрутизаторе initialize, чтобы вручную добавить маршруты (в виде шаблонов маршрутизации или регулярных выражений) в требуемом порядке.


Резюме: Fix ваши маршруты так, чтобы они соответствовали разные вещи.

+0

Спасибо. Я смог устранить проблему (то есть сделать загрузку страницы без ошибок), добавив новый маршрут вверху: '' index ":" restaurant_locations "'. Похоже, что порядок маршрутов действительно имеет значение, поскольку добавление нового маршрута на дно ничего не делало, но добавление его сверху. –

+0

@JasonSwett: В зависимости от порядка маршрута в источнике есть игра, нет абсолютно никакой гарантии, что она будет работать. В зависимости от исходного порядка вы оставляете себя открытым для зависимых от браузера ошибок. Стандарт JavaScript не гарантирует, что итерация по клавишам объекта даст ключи в исходном порядке (http://stackoverflow.com/a/10624559/479863). –

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