Enyo custom event is not handled and undefined in simple example

511 views Asked by At

I'm learning the events in Enyo js framework and can't understand why I get the error and event onModelChanged is not handled. Error message is:

"Uncaught TypeError: undefined is not a function"

Code:

debugger; 
enyo.kind({
    name : "MyModel",
    kind: "enyo.Model",
    defaultSource: "mocked",
    published: {
        title : "not set",
        text : "not set",       
    },
    
    events : {
        onModelChanged : "",
    },
    
    handlers: {
        onModelChanged : "modelLoadedHandler" 
    },
    
    modelLoadedHandler : function(inSender, inEvent){
        debugger;
        console.log("handler in model");
        console.log(inEvent.textMsg);
        return true;
    },
        
    fetch : function(opts){
        this.inherited(arguments);
        debugger;
        this.doModelChanged({textMsg: "fire event"}); // Uncaught TypeError: undefined is not a function
            
    }       
        
});



var model = new MyModel();
model.fetch();

P.S. Leave this code as an answer not to be deleted by jsfiddle

enyo.kind({
    name: "MyMockSource",
    kind: "enyo.Source",
    fetch: function(model, opts) {
        if(model instanceof enyo.Model) {
            opts.success({title: "testing", text: "Some stuff"});
        } else {
            throw new Error("Model mock only");
        }
    }
});

new MyMockSource({name: "mocked"});

enyo.kind({
    name : "MyModel",
    kind: "enyo.Model",
    source: "mocked",
    attributes: {
        title : "not set",
        text : "not set",       
    },
    fetched: function(opts){
        this.inherited(arguments);
        enyo.log("fetched");
        // Do something here if you need to, otherwise you might want to overload
        // the parse method and set parse: true to modify the retrieved data
    },
    titleChanged: function(was, is) {
        enyo.log("Title is now: " + is);
    }
});

enyo.kind({
    name: "MyView",
    components: [
        {kind: "Button", content: "Fetch", ontap: "fetch"},
        {name: "title"},
        {name: "text"}
    ],
    bindings: [
        {from: "model.title", to: "$.title.content"},
        {from: "model.text", to: "$.text.content"}
    ],
    fetch: function() {
        this.set("model", new MyModel());    // Probably want to create model elsewhere
        this.model.on("change", enyo.bindSafely(this, "modelChanged"));
        this.model.fetch();
    },
    modelChanged: function() {
        this.log("Something happened to my model!");
    }
});

new enyo.Application({ name: "app", view: "MyView" });
2

There are 2 answers

2
Pre101 On BEST ANSWER

enyo.Model is not an enyo.Object (much less an enyo.Component). It does not support published properties or events. You want to define attributes for a model. You can still get notifications on property changes using the propertyChanged event or by using observers.

Also, you probably want to overload fetched if you want to know that fetching has completed. fetch possibly returns before the data has been fetched.

If you want to subscribe to events from outside then you probably want to bind to a specific property on the model or to the changed event using model.on('change') (note this is a different event system from the events: [] system used elsewhere.

Update: Here's a fiddle showing the various ways to work with the model and binding to data

http://jsfiddle.net/RoySutton/5jo0p7ar/

0
Webby Vanderhack On

When you use the event system in this way, you are typically expecting a component higher up the chain to handle the onModelChanged event, not the component that defines the event. Further, enyo.Model is a special case and uses a different observer mechanism, I believe. That's probably why you are getting "undefined" for the function call, because there is no magic mapping between onModelChanged to a doModelChanged method.