Unable to make Binding functional

Hi there,
I am starting a Enyo 2.3 project, but as a noob, i have been trying to make my bindings work for hours.

The problem is very simple: from mainView of bootplate-mvc, I want to bind an attribute from a model, but this model is a member of a Session controller. Binding is saved, but content is never set or refreshed.
I am not used to work with enyo, and it's very hard to do with undocumented 2.3.

Any clue ?

Here is a sample: https://gist.github.com/ArTiSTiX/b41a6bc9bdc2af783872

Thanks

Comments

  • edited January 2014
    Assuming "MyApp.Model" is a type of enyo.Model, currentUser is of kind "ModelController" with model of "MyApp.Model", and the name of the ModelController is currentUser, and the rest of your code is okay, insert the word "model" between currentUser and name and change ".toolbar.content" to ".$.toolbar.content". It may work without ModelController intermediary but prob better to use with one.
    bindings: [{
            from: ".app.$.session.currentUser.model.name", 
            to: ".$.toolbar.content"
  • I finally managed to make it work.
    Indeed, there was an error with '.toolbar.content' missing the '$' character (i must have misunderstood its function). This is the mistake which drove me crazy.

    But I also made a big mistake with the session controller which I instanciated 2 times.
    I was making a app.$.session = new Session() (just before app.start()) while it was already instanciated with MyApp.components... I suppose the bindings were still linked to the old instance.

    3 hours of work... I must make tutorials once my project is finished.

    One question: Why should I use a Model controller for currentUser ?
    I directly Store the User Model instance, as I would do in a Rails app.
  • The ModelController is used in a situation where the model may not be always available. For example, you're creating a view that's bound to fields of your model, but you're doing a AJAX load to bring in the model so that binding will need to change. It basically acts as a proxy -- when the model in the ModelController changes, it refreshes all the bindings into it to handle the new data.
  • Ok, that's what i need for my views.
    I'm trying to make it work, but, nothing.

    I have a ModelController, with Show method which is intented to populate model (findlocal or fetch, i will refactor it into my custom model kind):
    enyo.kind({
        name: "Beshamel.Controllers.Foods",
        kind: "enyo.ModelController",
    
        show: function(food_id) {
            this.set('model',enyo.store.findLocal('MyApp.Models.Food',{id: food_id}))
    
            if (this.model ==  undefined)
            {
                this.set('model',new MyApp.Models.Food({id: food_id}))
                var model= this.model;
                this.model.fetch({
                    fail: function() {model.destroyLocal(); alert('NOT FOUND')}
                });
            }
    
            app.$.mainLayout.addPanel('MyApp.Views.Foods.Show');
        }
    })
    And here is the view (added to a panel arranger):
    
    enyo.kind({
        name: "MyApp.Views.Foods.Show",
        kind: "enyo.Control",
        components: [
            {content: '',
                style:"background:white;",
                fit: true,
                classes: 'enyo-fit',
                components: [
                {name: 'title',tag: 'h1', content: 'Title'}
                ]
            }
        ],
        bindings: [
            {from: '.app.$.foods_controller.model.name', to: '.$.title'}
        ]
    })
    I can see the existing binding through console, and attributes are correctly popuplated, but Title is stillshowing.
    I tried to use this.set('model',...) or assigning it directly, but it's still not working.

    Thank you for help and clear answer.

    Subsidiary Question: Collections don't need specific controllers ? I was planning to add a collection to this controller.
    My next problem is, if i need to keep models synced, it may be very complex to emulate relational, without modelcontrollers. I thought it would be easy to have nested models accessible via food.nested_model.child_model ...
  • Damn... found my mistake. I must bind to '.$.title.content'... I will get used to... I hope.

    So my questions are still pending... But it seems that direct assignation updates bindings too, so... maybe i will have no issue to add bindings on nested models.
    And adding a collection to this ModelController may not be hard.
  • Collections act as their own controllers, you really only need ModelController when you're working with a single Model.
  • I'm having troubles again, with Collections nested into Models.
    I'm searching for the best way to create Relational Models, but bindings doesn't want to follow my way.

    Please, tell me where i'm wrong... and if you know, how should i do right.
    I hope i may not be forced to wait for relational modelling feature in Enyo.
    enyo.kind({
        name: "Beshamel.Models.Recipe",
        kind: "Beshamel.Model",
        url: "/recipes",
        attributes: {
            id : null,
            name: '',
            description: '',
            title: function () {
                return this.get("name");
            },
            action: function () {
                return 'recipes/show/'+this.get("id");
            }
        },
        parse: function(data) {
            this.equipments = new enyo.Collection(data['equipments']);
            this.tasks = new enyo.Collection(data['tasks']);
            this.ingredients = new enyo.Collection(data['ingredients']);
            delete data['equipments'];
            delete data['tasks'];
            delete data['ingredients'];
            return data;
        }
    })
    In this code, i can't make a binding to ".app.$.recipes_controller.model.tasks", while i can on ".app.$.recipes_controller.model.name". RecipesController is no longer a ModelController, since I build the view once the model is instanciated (so its reference never change for the view), because it was crushing access to other members (like collections nested into controller).

    I tried many ways: instanciate collection in constructor, before sup, failed to use published properties, set, or setAttributes.
    In console.log, before building view, everything is ok, instanciated, populated.

    Thank you, my app is growing pretty fast, but could be almost finished if i could deal with those crazy bindings.
  • Cole is in the middle of implementing relational support for models, but that work isn't ready for release yet.
  • edited February 2014
    I encountered similar issues and didn't find a great solution.

    Some additional things to try:
    1. Try "refreshBindings" in the view, after calling your the fetch.
    2. Or send in a success function into fetch and manually change things.
    3. Or try "addListener" in view +/- "triggerEvent" in model.
    4. Or send Cole coffee beans with high caffeine content.
  • I will investigate. I have to finish my prototype for next week, and i need to access to those collections from view.
    Any not great solution to provide before Relational is in pre-release ?
  • I made an ugly fix:
        create: function() {
            this.inherited(arguments);
            this._recipes= new Beshamel.Collections.Recipe();
            this._tasks= new Beshamel.Collections.Task();
            this._ingredients= new Beshamel.Collections.Ingredient();
            this._equipments= new Beshamel.Collections.Equipment();
        },
        show: function(recipe_id) {
            this.model = enyo.store.findLocal('Beshamel.Models.Recipe',{id: recipe_id})
    
            if (this.model ==  undefined)
            {
                this.model = new Beshamel.Models.Recipe({id: recipe_id})
                var model= this.model;
                var _this = this;
                this.model.fetch({
                    success: function() {
                        app.$.mainLayout.setView('Beshamel.Views.Recipes.Show');
                        _this._tasks.reset(model.tasks.records);
                        _this._ingredients.reset(model.ingredients.records);
                        _this._equipments.reset(model.equipments.records);
                    },
                    fail: function() {model.destroyLocal(); alert('NOOOT FOOOOOOOUUUUUUND')}
                });
            }
            else
            {
                app.$.mainLayout.setView('Beshamel.Views.Recipes.Show');
                this._tasks.reset(model.tasks.records);
                this._ingredients.reset(model.ingredients.records);
                this._equipments.reset(model.equipments.records);
            }
        },
    I duplicated the collection into the controller.
    I really don't understand why collections are not accessibles from models. I hope Relationnal will fix it soon. Sounds amazing.
Sign In or Register to comment.