1

I learned that instead of using model.findAll and write code in call back function of findAll we can achieve same by using new model.List({}). E.g., jsfiddle --> http://jsfiddle.net/CRZXH/48/ .. in this jsfiddle example List implementation works but findOne fails.

   var people = new Person.List({});

        return can.Component({
            tag: 'people',
            template: initView,
            scope: {
                people: people
                }
        })

Above example works fine, initially people is assigned with empty object but after ajax call complete people variable is updated with list and view updates on its own.

How to achieve the same in case of findOne?

 var person = PersonModel.findOne({});

    can.Component({
        tag: 'person',
        template: initView,
        scope: person
    })

This fails....

I did work around as below :

 var person;
    PersonModel.findOne({},function(data){
      person = data
    });

    can.Component({
        tag: 'person',
        template: initView,
        scope: person
    })

This works only if I add asyn=false in findeOne ajax call.

Abhi
  • 38
  • 5

2 Answers2

1

I got solution for this problem from http://webchat.freenode.net/ @daffl

Solution : http://jsfiddle.net/CRZXH/49/

can.Model.extend('Person', {
    findOne: 'GET api/metadata',
    getMetadata: function() {
        var result = new Person();
        Person.findOne().then(function(data) {
            result.attr(data.attr(), true);
        });
        return result;
    }
}, {});
// Person component which uses findOne
can.Component({
    tag: 'person',
    scope: function() {
        return {
            person: Person.getMetadata()
        }
    }
})
Abhi
  • 38
  • 5
0

1- the ID for findOne is mandatory

findOne({id: modelId})

2- You can put the person model in a viewmodel (AKA component scope) and not passe the value use can.stache plugin and can.map.define plugin for this

can.fixture({
    "GET api/people":function(){
  return [
    {id: 1, name: "Person 1"},
    {id: 2, name: "Person 2"}
  ];
            },"GET api/people/{id}":function(request,response){
  return {id: request.data.id, name: "Person "+request.data.id}
}
});

can.Model.extend('Person',{
     findAll: 'GET api/people',
    findOne: 'GET api/people/{id}',
},{});

can.Component.extend({
    tag:'x-person',
    scope:{
        define:{
            person:{
                get:function(currentPerson,setFn){
                    Person.findOne({id: 2}, setFn);
                }
            }

        }
    }

});

var frag=can.view('personTmpl',{});

$('#main').html(frag);

Here is the fiddle http://jsfiddle.net/cherif_b/egq85zva/

Cherif BOUCHELAGHEM
  • 1,126
  • 2
  • 14
  • 21
  • Thanks for the answer it works, but I am looking for something equivalent to new Person.List({}) in findOne. – Abhi Sep 08 '14 at 17:47