2015-08-02 2 views
2

Я пытаюсь загрузить json-файл в коллекцию Backbone, но я продолжаю использовать метод TypeError: Can not call 'to undefined'.Магистраль: TypeError: не удается вызвать метод 'apply' of undefined

В частности:

return Backbone.$.ajax.apply(Backbone.$, arguments); 
TypeError: Cannot call method 'apply' of undefined 

Вот мой сценарий:

var Backbone = require('backbone'); 
var PostModel = Backbone.Model.extend(); 
var PostCollection = Backbone.Collection.extend({ 
    model: PostModel, 
    url: "data.json", 
    parse: function(data) { 
    return JSON.parse(data); 
    } 
}); 

var posts = new PostCollection(); 
posts.fetch({reset: true}); 
posts.bind('reset', function() { console.log(posts); }); 

Является ли это из-за асинхронном? Как это исправить?

ответ

0

Если запустить свой код в nodejs среде вместо браузера, то вы могли бы использовать najax модуль для выполнения запросов

var Backbone = require('backbone'), 
    najax = require('najax'); 

// set alias to najax 
Backbone.ajax = najax; 

var PostModel = Backbone.Model.extend(); 
var PostCollection = Backbone.Collection.extend({ 
    model: PostModel, 
    url: "data.json", 
    parse: function(data) { 
     return JSON.parse(data); 
    } 
}); 

var posts = new PostCollection(); 
posts.fetch({reset: true}); 
posts.bind('reset', function() { console.log(posts); }); 

EDIT

Если файл data.json в той же папке, как вы указали в комментарии, то вам не нужно использовать url и fetch. Вы должны сначала требуют данных, а затем инициализировать коллекцию с ними:

var Backbone = require('backbone'), 
    data = require('./data.json'); 

var PostModel = Backbone.Model.extend(); 
var PostCollection = Backbone.Collection.extend({ 
    model: PostModel, 
    parse: function(data) { 
     return JSON.parse(data); 
    } 
}); 

var posts = new PostCollection(data, {parse: true}); 
+0

с этим я получаю ошибку: '= SSL l.protocol.indexOf ('HTTPS') === 0, TypeError: Невозможно вызвать метод 'IndexOf' из null' – bumblejungle

+0

Вам нужно обеспечить абсолютное' url' к вашему источнику данных, например 'http: // mysoure.com/data.json' вместо' data.json' Обратите внимание, что протокол (http или https) является обязательным. –

+0

Что делать, если файл json находится в той же папке, что и скрипт? И не в Интернете? – bumblejungle

0

Основная проблема заключается в том, что Backbone.$.ajax является undefined, так что вы не можете запустить его с помощью apply()

Не видя больше кода, что я могу» С уверенностью скажите, почему это, но мое образованное предположение, вы используете что-то вроде Browserify или Webpack.

До тех пор, пока, я думаю, самая последняя версия Backbone, Backbone. $ Не автоматически ссылалась на jQuery или Zepto в средах commonJS (например, Node) - вам нужно прикрепить их вручную. Убедитесь, что вы установили JQuery, а затем попробовать:

var Backbone = require('backbone') 
var $ = require('jQuery'); 
Backbone.$ = $; 
return Backbone.$.ajax.apply(Backbone.$, arguments); 
0

Я столкнулся с этой же проблемой сегодня, при попытке проверить JQuery & Backbone, используя npm test файл.

Задача: Метод jQuery.ajax() не является статической функцией. Таким образом, они не существуют во время компиляции в версиях jQuery 1.x и 2.x: function ajax() или this.ajax: function(). Метод .ajax() динамически построен на этапе инициализации времени. Он создается, когда jQuery загружается в DOM, но недоступен без DOM. Поскольку вы используете Node.js, вы должны макетировать поддельный объект DOM (глобальный документ &), а затем передать объект окна в jQuery для создания метода $ .ajax. Затем вы можете сопоставить это с ajax-методом Backbone, чтобы он работал. Глобальный объект документа также требуется для инициализации jQuery.

Это код jQuery, который создает динамический метод $.ajax().Я просто указав его, так что вы можете увидеть, что она строится динамически в этом коде:

jQuery.each([ "get", "post" ], function(i, method) { 
    jQuery[ method ] = function(url, data, callback, type) { 

     // shift arguments if data argument was omitted 
     if (jQuery.isFunction(data)) { 
      type = type || callback; 
      callback = data; 
      data = undefined; 
     } 

     // The url can be an options object (which then must have .url) 
     return jQuery.ajax(jQuery.extend({ 
      url: url, 
      type: method, 
      dataType: type, 
      data: data, 
      success: callback 
     }, jQuery.isPlainObject(url) && url)); 
    }; 
}); 


jQuery._evalUrl = function(url) { 
    return jQuery.ajax({ 
     url: url, 

     // Make this explicit, since user can override this through ajaxSetup (#11264) 
     type: "GET", 
     dataType: "script", 
     cache: true, 
     async: false, 
     global: false, // <- This 1.x line is removed from 2.x 
     "throws": true 
    }); 
}; 

Причина: unminified версия JQuery, упоминает следующее в верхней части файла:

// For environments that do not have a `window` with a `document` 
// (such as Node.js), expose a factory as module.exports. 
// This accentuates the need for the creation of a real `window`. 
// e.g. var jQuery = require("jquery")(window); 
// See ticket #14549 for more info. 

я нашел тот же код, документированный в этой ссылке НПМ, но у меня было трудное время получить свой макет код DOM для работы: https://www.npmjs.com/package/jquery#node

Решение: T О исправить свой код, вы можете добавить этот код, который был мощеным вместе с этой jsdom GitHub ссылки: https://github.com/tmpvar/jsdom#how-it-works

var jsdom = require("jsdom").jsdom; 

var markup = "<html><body></body></html>"; // Creates a default DOM. 
var options = {}; // See: https://github.com/tmpvar/jsdom#how-it-works 

global.document = jsdom(markup, options); // Creates a document object from Node. 
global.window = global.document.defaultView; // Creates a window object from Node. 

// Passes the window object into jQuery, so that it can create the .ajax() method: 
const $ = require("jquery")(global.window) 

// This maps the dynamic .ajax method into Backbone: 
Backbone.$.ajax = $.ajax; 

Это должно исправить ваш Node.js код & НПХ тесты, и вы будете счастливо на твой путь! :-)

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