Почему «функция выборки» автоматически вызывает «функцию синтаксического анализа» в коллекции backbone.js?

Я пытаюсь разобрать свой файл json в коллекцию и модель Backbone, как показано ниже.

Это файл .json

[
{
    "type": "rect",
    "x": 10,
    "y": 10,
    "w": 100,
    "h": 100,
    "color": "red"
},
{
    "type": "arc",
    "x": 210,
    "y": 20,
    "w": 200,
    "h": 150,
    "color": "blue"
}
]

И у меня также есть файл .html, как показано ниже.

    <script>
    $(function() {
        var JSONModel = Backbone.Model.extend({});

        var MyCollection = Backbone.Collection.extend({
            model : JSONModel,
            url : 'profiles.json',
            initialize : function() {
                alert("init");
            },
            parse : function(response) {

                for (var i = 0; i < response.length; i++) {
                    var tmpModel = new JSONModel();
                    tmpModel.set({
                        type : response[i].type,
                        x : response[i].x,
                        y : response[i].y,
                        w : response[i].w,
                        h : response[i].h,
                        color : response[i].color
                    });
                    this.add(tmpModel);
                    alert("inserting" + i);
                }

                return response;
            }

        });

        var collection = new MyCollection();
        collection.fetch();
        alert(collection.length);


    });
</script>


Q.

1. Почему в этом коде функция выборки вызывает функцию разбора?

2. Есть ли какая-либо другая функция, которая вызывается из функции выборки?

3. Как вы думаете, как я могу исправить этот код, чтобы получить объект json? Я не могу получить "коллекцию.длина" в этом коде.

Пожалуйста помоги.


person Jinny Song    schedule 20.11.2015    source источник


Ответы (2)


Пожалуйста, ознакомьтесь с моими комментариями ниже по вашему вопросу:

1. В этом коде, почему функция выборки вызывает функцию разбора?

Ответ: При расширении Backbone.Collection вы переопределили функцию обратного вызова parse и Backbone внутренне вызывает функцию parse всякий раз, когда мы пытаемся fetch собрать коллекцию. Это стандартный вызов. Я не думаю, что вы должны Или можете изменить это поведение.

2. Есть ли какая-либо другая функция, которая вызывается из функции выборки?

Ответ: Насколько я знаю, я не думаю, что какая-либо другая функция обратного вызова вызывается при вызове fetch. Почему вы ищете его? Каковы ваши требования к этому пункту? Какая-то конкретная причина?

3. Как вы думаете, как я могу исправить этот код, чтобы получить объект json? Я не могу получить "коллекцию.длина" в этом коде.

Ответ: Вам придется подождать, пока мы получим данные, поэтому нам нужно добавить обработчик success следующим образом:

collection.fetch({
  success: function(collection){
    // Callback triggered only after receiving the data.
    console.log(collection.length); 
  }
});
person vijayP    schedule 20.11.2015
comment
Спасибо большое. Второй вопрос был немного двусмысленным, извините. Как вы сказали, вызовы fetch анализируются внутри. И я имел в виду, есть ли какая-либо другая функция, такая как синтаксический анализ, которая вызывается из функции выборки. - person Jinny Song; 20.11.2015

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

Все, что вам нужно сделать, это:

var MyCollection = Backbone.Collection.extend({
  model: JSONModel,
  url: 'profiles.json',
  initialize: function() {
    console.log("init");
  }
});

var collection = new MyCollection();
collection.fetch({
  success: function(collection, response) {
    console.log(collection.length);
  }
});

Если вы определите метод parse, магистраль выполнит его перед обновлением модели и выполнением других обратных вызовов (переданных в параметрах), это требуется только в том случае, если вы хотите изменить полученные данные перед их дальнейшей обработкой ( обновление модели/коллекции, переход к обратным вызовам и т. д.).

Например, предположим, что ваш .json содержит следующее:

{
 "someKey": "some Info",
 "data": [{
  "type": "rect",
  "x": 10,
  "y": 10,
  "w": 100,
  "h": 100,
  "color": "red"
 },
 {
  "type": "arc",
  "x": 210,
  "y": 20,
  "w": 200,
  "h": 150,
  "color": "blue"
 }]
}

Затем вы захотите проанализировать это и вернуть фактический массив, например:

parse: function(response){
  console.log(response.someKey); // do somethig with this if required
  return response.data;
}

В вашем случае .json содержит массив объектов, backbone проанализирует каждый объект в массиве в модель указанного типа и добавит его в вашу коллекцию. Нет необходимости указывать метод parse.

И да, есть другие методы, которые вызываются внутри, например sync, toJSON и т. д. У каждого из них есть своя обязанность (и может быть переопределена), которая указана в документация.

person T J    schedule 20.11.2015
comment
Спасибо большое. Я полностью понимаю эту проблему из-за вас! Это было так полезно!! - person Jinny Song; 20.11.2015
comment
Могу ли я просто добавить функцию успеха в MyCollection, сложно? - person Jinny Song; 20.11.2015
comment
@JinnySong технически вы можете сделать collection.fetch({ success: collection.successHandler }); Но я не предлагаю этого. На мой взгляд, то, что происходит после выборки, вероятно, должно обрабатываться тем, кто вызывает fetch. Но ничто не мешает вам сделать это технически. stackoverflow.com/help/someone-answers - person T J; 20.11.2015