0

過去に、テンプレートを使用してコレクションをレンダリングおよび表示したい場合は、コレクションの「each」メソッドを呼び出すだけでした。モデルごとに、モデルごとに新しい単一のビューを作成し、それを $el に追加します。しかし、この場合、これは機能しません。テンプレートに入力タイプのテキストがあり、モデルごとに新しい入力を表示したくありません。どうにかしてコレクションをテンプレートに渡し、テンプレート内のコレクションを反復処理したいと思います。また、このビューの新しいインスタンスを作成するときに、コレクションがメイン アプリ ビューを介して渡されることも注目に値します。

// clientsview.js

define(
[
    'backbone',
    'ClientView',
    'Clients'
], function(Backbone, ClientView, Clients) {

ClientsView = Backbone.View.extend({

    tagName: '#page',
    template: _.template( $('#allClientsTemplate').html() ),


    initialize: function() {
        this.render();
    },

    render: function() {

        // var that = this;
        console.log('collection');
        console.log(this.collection);// successfully returns collection
        console.log('template');
        console.log(this.template);// successfully returns template function


        // This causes an error: 
        //Uncaught TypeError: Cannot call method 'toJSON' of undefined 
        var tmpl = this.template({ clients: this.collection.toJSON() });

        return this;

    }

});
return ClientsView;
});

index.html の私のテンプレート

// index.html
<script id="allClientsTemplate" type="text/template">
// I do not want create an input for every single model
// but I need the input to be part of the view.
<input type="text" class="table-search" id="search" autocomplete="off"   placeholder="Search Clients…">
<table class="table" id="tblData">
    <thead>
        <tr>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Status</th>
        </tr>
    </thead>
    <tbody id="tblDataBody">

        <% _.each(clients, function(client) { %>

            <tr>
                <td><a href=""><%- client.first_name %></a></td>
                <td><a href=""><%- client.last_name %></a></td>
                <td><a href=""><%- client.status %></a></td>
            </tr>

        <% }); %>

    </tbody>
</script>

メイン アプリ ビュー内からクライアント ビューをインスタンス化しています。

define(
    [
        'jquery',
        'underscore',
        'backbone',
        'AddClientView',
        'ClientsView',

    ], function( $, _, Backbone, AddClientView, ClientsView ) {

    AppView = Backbone.View.extend({

        initialize: function() {

            // var addClientView = new AddClientView({ collection: this.collection });
            var clientsView   = new ClientsView({ collection:this.collection });


        }

    });
    return AppView;
});

そして、初期化メソッドからメイン アプリ ビューをインスタンス化しています。

define('App', [
    'jquery',
    'underscore',
    'backbone',
    'Router',
    'bootstrap',
    'Clients',
    'AppView'
], function($, _, Backbone, Router, bootstrap, Clients, AppView) {

    function initialize() {

        // for custom global events
        window.vent = _.extend( {}, Backbone.Events )

        var app = new Router();
        Backbone.history.start();


        // probably more appropriate to do this in app view
        var clients = new Clients;// Get collection of clients


        clients.fetch().then( function() {// fetch client collection from db
            new AppView({ collection: clients });
        });

    }
    return {
        initialize: initialize
    };
});

私の初期化メソッドは main.js から呼び出されています:

// main.js
require.config({
    shim: {
        'underscore': {
         exports: '_'
        },
        'backbone': {
            deps: ['underscore', 'jquery'],
            exports: 'Backbone'
        },
        'bootstrap': {
            deps: ['jquery'],
            exports: 'bootstrap'
        }
    },
    paths: {
        'text'          : 'lib/require/text',
        'jquery'        : 'lib/jquery/jquery-1.9.1',
        'underscore'    : 'lib/underscore/underscore',
        'backbone'      : 'lib/backbone/backbone',
        'bootstrap'     : 'lib/bootstrap/bootstrap',
        'App'           : 'app',
        'Router'        : 'router',
        'AppView'       : 'views/app/appview',
        'Client'        : 'models/clients/client',
        'Clients'       : 'collections/clients/clients',
        'ClientView'    : 'views/clients/clientview',
        'ClientsView'   : 'views/clients/clientsview',
        'AddClientView' : 'views/clients/addclientview'
    }
});
require(['App'], function(App) {
    App.initialize();
});

このアプローチを試みるとエラーが発生します (Uncaught TypeError: Cannot call method 'toJSON' of undefined)。どうすればこれを機能させることができますか?

4

2 に答える 2

2

コレクションをインスタンス化し、アイテムを追加してから、ビューをインスタンス化し、コレクションを渡す必要があります。

var clients= new Clients();
clients.add({FirstName: 'Joe', LastName: 'Blow', Status: 'Active' });

var clientsView = new ClientsView({collection: clients});

テンプレートも変更する必要があります。

<% _.each(collection, function(client) { %>
<tr>
    <td><a href=""><%- client.get('FirstName') %></a></td>
    <td><a href=""><%- client.get('LastName') %></a></td>
    <td><a href=""><%- client.get('Status') %></a></td>
</tr>
<% }); %>
于 2013-03-16T23:24:49.023 に答える
1

あなたのバックボーンは正しいです。ここでの問題は、AppView をインスタンス化するときに fetch によって作成された promise を介してデータを渡していないことです。

あなたのコード:

clients.fetch().then( function() {// fetch client collection from db
     new AppView({ collection: clients });
});

そのはず:

clients.fetch().then( function(resp) {// fetch client collection from db
     new AppView({ collection: resp.data });
});
于 2015-05-20T20:28:04.283 に答える