简体   繁体   中英

Ember-Model EmbeddedHasManyArray not updating in template's each helper

I am using ember-model for a simple invoicing app, i am new to ember and i cannot fix what's happening here, basically i am using ember-model's hasMany for embedded nested data, (the items for each invoice are in an array), i tried putting the code on jsbin and jsfiddle but it doesn't work up there, so for those who have time to help i put up an archive on my dropbox here : Ember-Model hasMany not updating in template's {{#each}}

To reproduce the bug, navigate to an invoice, then navigate to another invoice using the links, watch the items not updating as if they were stuck, but if you reload the page you will get the right items, what am i doing wrong :/ ?

The following code is of course a very simplified version of my actual app but it does reproduce the bug..

Thanks to anyone willing to help.

Index.html

<!DOCTYPE html>
<html>
<head>
  <meta name="description" content="Ember - Starter" />
  <meta charset=utf-8 />
  <title>Ember-Model</title>
  <script src="libs/jquery-1.9.1.js"></script>
  <script src="libs/handlebars-1.0.0.js"></script>
  <script src="libs/ember-1.1.2.js"></script>
  <script src="libs/ember-model-latest.js"></script>
  <script src="app.js"></script>
</head>
<body>

<script type="text/x-handlebars">
  <h1>Invoices</h1>
  {{ outlet }}
</script>

<script type="text/x-handlebars" data-template-name="factures">
{{#each}}
    <ul>
        <li>{{#link-to 'facture' this}}{{title}}{{/link-to}}</li>
    </ul>
{{/each}}
  <hr/>
    {{outlet}}
</script>

<script type="text/x-handlebars" data-template-name="facture">
<h2>Items for {{title}}</h2>
{{#each items}}
<ul>
  <li>{{desc}}</li>
</ul>
{{/each}}
</script>

</body>
</html>

App.js

var App = Ember.Application.create();

// ROUTER
App.Router.map(function () {
    this.resource('factures', function () {
        this.resource('facture', {
            path: '/:facture_id'
        });
    });
});

App.FacturesRoute = Ember.Route.extend({
    model: function (params) {
        return App.Facture.find();
    }
});

App.FactureRoute = Ember.Route.extend({
    model: function (params) {
        return App.Facture.fetch(params.facture_id).then(function (modelData) {
            return App.Facture.find(params.facture_id);
        });
    }
});

// Redirect
App.IndexRoute = Ember.Route.extend({
    redirect: function () {
        this.transitionTo('factures');
    }
});


// MODELS
var attr = Ember.attr,
    hasMany = Ember.hasMany,
    belongsTo = Ember.belongsTo;

// Factures
App.Facture = Ember.Model.extend({
    title: attr(),
    items: hasMany('App.Item', {
        key: 'items',
        embedded: true
    })
});

App.Facture.adapter = Ember.FixtureAdapter.create();

// Facture
// -> [ Items ]
App.Item = Ember.Model.extend({
    desc: attr(""),
    qty: attr("number"),
    price: attr("string")
});

// FIXTURES

App.Facture.FIXTURES = [
{
    id: 1,
    title: "Invoice #1",
    items: [
        {id: 1, desc: 'An Item for #1', qty: 2, price: "45"}, 
        {id: 2, desc: 'An Item for #1', qty: 5, price: "75"}
    ]
}, 
{
    id: 2,
    title: "Invoice #2",
    items: [
        {id: 1, desc: 'An Item for #2', qty: 2, price: "250"},
        {id: 2, desc: 'An Item for #2', qty: 5, price: "200"}
    ]
}];

Your items id's should be unique, ember model doesn't care if it's embedded or not, if it sees the same id it returns the model that's already existing for that id.

http://emberjs.jsbin.com/eKibapI/1/edit

App.Facture.FIXTURES = [
{
    id: 1,
    title: "Invoice #1",
    items: [
        {id: 1, desc: 'An Item for #1', qty: 2, price: "45"}, 
        {id: 2, desc: 'An Item for #1', qty: 5, price: "75"}
    ]
}, 
{
    id: 2,
    title: "Invoice #2",
    items: [
        {id: 3, desc: 'An Item for #2', qty: 2, price: "250"},
        {id: 4, desc: 'An Item for #2', qty: 5, price: "200"}
    ]
}];

I'm not sure why you're wrapping App.Facture.find() in App.Facture.fetch() . Note that the way it is set up the return of your callback function will not be returned by your model hook. Try the following:

App.FactureRoute = Ember.Route.extend({
    model: function (params) {
        return App.Facture.find(params.facture_id);
    }
});

Of course this is also the default behavior, so you should be able to just remove the entire App.FactureRoute .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM