Extending Kinds

edited March 2012 in Enyo 2
I'm trying to extend enyo.Repeater to add the ability to add on additional rows after the control is built. So I created a new Kind and try to add a rowsChanged handler so I could add the additional additions but it doesn't fire when I change the rows property.

If I copy the property change handler to enyo.Repeater it works fine.

What am I doing wrong?

enyo.kind({
	name: "RepeaterPlus",
	kind: "enyo.Repeater",

	rowsChanged: function(){
		enyo.log('changed');
	}
});

Comments

  • try this:
    
    rowsChanged: function(){
    	this.inherited(arguments);
    	enyo.log('changed');
    }
    
    See the documentation for the inherited method for more details.
  • edited March 2012
    That didn't seem to make a difference.

    Also I have noticed that I can not add any additional published properties to my RepeaterPlus kind they are not showing in the console. But the kind type is indeed "RepeaterPlus"
    enyo.kind({
    	name: "RepeaterPlus",
    	kind: "enyo.Repeater",
    
    	published:{
    		test:'value'
    	},
    
    	rowsChanged: function(){
    		this.inherited(arguments);
    		enyo.log('changed');
    	}
    });
  • Can you post your full code for where you are creating your RepeaterPlus object?
  • edited March 2012
    Here it is
    {kind: "RepeaterPlus", name:"list", rows: 0, onSetupRow: "setupRow", ontap: "itemTap", components: [
    			{name: "items", kind: "ToolDecorator", classes: "row-item"}
    		]}
  • edited March 2012
    I've taken a look at the enyo.Repeater kind, and it doesn't have a published property named 'rows'.

    Are you intending to inherit from VirtualRepeater maybe?

    EDIT: actually that doesn't have a 'rows' property either so I'm not sure what you're trying to do :-S
  • OK that all looks like it should work. Presumably you are changing the property by calling setRows? As far as I'm aware, a sub-kind should be able to implement the Changed method for a property of a parent kind.
  • Yep:

    this.$.list.setRows(feed.entry.length);

    Also if I put the RepeaterPlus kind in the file implementing RepeaterPlus it works as expected.


  • The enyo.Repeater() code doesn't call "rowsChanged()" in the create method, as it doesn't have a create method. If you want to make sure your rowsChanged call is called at least once, you should put that call in your own create() method.

    I don't know if we'd take a pull request that added this to the Repeater kind... we're not consistent about calling the changed method in a constructor, usually only doing it when there's a known effect.
  • Hi Ben,

    Are you saying that if I add my own create method in RepeaterPlus that calls "rowsChanged()" that my own rowsChanged() function will be called whenever the property changes? Or just when create() is executed?
  • It would be called at creation time. Your rowsChanged method should be called whenever anyone calls setRows, but the current code just reads the rows value and never alters it from design time.
  • I was finding that rowsChanged method never got called when I changed the rows property with setRows()

    Also published properties in my RepeaterPlus kind are not showing up on my RepeaterPlus object so my problems are still unsolved.
  • edited March 2012
    I just setup a jsfiddle for this at http://jsfiddle.net/unwiredben/Kaj3S/ -- I'm seeing two "changed" messages show up in my console log when I hit run.

    Calling this.inherited failed because there was no earlier definition so I commented it out. I feel like this is a bug, so I'm talking with the core maintainers -- I think this.inherited should be a no-op if there's no parent method.
  • It would be even better if super-kinds would simply honor their interface. If you create a property, it's propnameChange method should be set to an empty method if there isn't one defined (rather than have the inherited method check itself and silently fail).
  • I'm proposing that the code that sets the internal _inherited property on each method of a kind set that to enyo.nop (a do nothing method) when there's no super method... same effect, and doesn't slow down the this.inherited() call.
  • That fiddle works for me to Ben, even when I switched over to b3. I will do some more debugging and see if I can isolate the problem.
  • edited March 2012
    I guess it'll be faster, it just doesn't seem right semantically. I would expect a random new method that only appears in a subkind to throw an exception when attempting to use it's non-existent super method, whereas if a super-kind declares a property, I expect that it would implement the changed method for that property even if it's enyo.nop.

    Not a huge deal obviously, maybe I'm just thinking too OO..
  • i'd agree with @omastudios. Perhaps changing Object.addGetterSetter to set the nop like it does for get* and set*
    enyo.Object.addGetterSetter = function(inName, inValue, inProto) {
    	var priv_n = inName;
    	inProto[priv_n] = inValue;
    	//
    	var cap_n = enyo.cap(priv_n); 
    	var get_n = "get" + cap_n;
    	if (!inProto[get_n]) {
    		inProto[get_n] = function() { 
    			return this[priv_n];
    		};
    	}
    	//
    	var set_n = "set" + cap_n;
    	var change_n = priv_n + "Changed";
    	if (!inProto[set_n]) {
    		inProto[set_n] = function(v) { 
    			this._setProperty(priv_n, v, change_n); 
    		};
    	}
    
    	// added this block ...
    	if(!inProto[change_n]) {
    		inProto[change_n] = enyo.nop;
    	}
    };
  • edited March 2012
    Yeah, that makes sense and it is cleaner. I'll see what Scott & Steve think in the pull request - https://github.com/enyojs/enyo/pull/46
  • OK, looks like the core team went with the simpler fix, just making this.inherited() never fail. It's already pushed into the master branch, see https://github.com/enyojs/enyo/commit/9e7a1d69ee722040d81181b1d11dde86ed49c811
Sign In or Register to comment.