These are chat archives for canjs/canjs

5th
Jun 2015
opolyo01
@opolyo01
Jun 05 2015 00:48
hey guys, I am stuck with updating dimensionList attribute of ViewModel
var ViewModel = {
isSelectedDimension: '',
define: {
dimensionList: {
get: function() {
Here's the event that tries to update it
'.search-dimension keyup': function(el, ev){
var searchTerm = el.val();
var filteredDimensions = _.filter(this.scope.dimensionList(), function(dim){
return dim.title.indexOf(searchTerm) !== -1;
});
this.scope.attr('dimensionList', filteredDimensions);
},
somehow this.scope.dimensionList() always stays the same
I haven't worked with can.Components much, so might be missing something fundamental
Matthew Phillips
@matthewp
Jun 05 2015 14:42
If you are using get then dimensionList is a compute. You can't replace it. You probably don't want a get in this case.
Chris Gomez
@akagomez
Jun 05 2015 14:56
@opolyo01 Is this what you’re going for? http://jsbin.com/dagefe/1/edit?js,console
@matthewp We can replace computes on can.Map’s with { type: ‘compute’ }. It’s just not documented yet: bitovi/canjs#1690
opolyo01
@opolyo01
Jun 05 2015 15:46
@akagomez Yes, I want something like this. Though, I am not sure I like this whole serialize thing. At first I can do -- map.attr('list') // [1, 2, 3] And after setting new array on the list I get a serialized object. Let me check that this will even auto update in my stache template if I keep serialized version of it
opolyo01
@opolyo01
Jun 05 2015 15:52
@matthewp Ok so things with get should be immutable? But I thought the purpose of compute objects to be updated and bindable to a template. If I had a simple can.List outside of Map then everything would just work by updating the list, but what is the process of updating properties under can.Map within define?
Chris Gomez
@akagomez
Jun 05 2015 15:57
@opolyo01 The serialize was for demonstration purposes only. Sorry to confuse.
@opolyo01 Here’s a better example: http://jsbin.com/dagefe/2/edit
Chris Gomez
@akagomez
Jun 05 2015 16:08
@opolyo01 I think @matthewp Was misinterpretting your question. Computes are the low-level utility that backs can.Map.define. A compute takes a property on set… compute(newVal). So if you unknowingly attempted to set list to something else, like.. map.attr(‘list’, someOtherList), you’ll actually be passing someOtherList to the compute, like this.. map.list(someOtherList), as opposed to map.list = someOtherList. Does that make sense?
opolyo01
@opolyo01
Jun 05 2015 16:18
Ok thanks. I found an issue. So get in can.Map define actually being called only if accepts an argument with the new value. I thought, by doing map.attr('list', someOtherList) it will automatically bind to template without me writing the logic in get. So now I have this define: {
dimensionList: {
get: function(filteredDimensions) { instead of define: {
dimensionList: {
get: function() {
Chris Gomez
@akagomez
Jun 05 2015 16:24
Can you share your get function? Or maybe summarize it? I wonder if it’s actually necessary for your case.
opolyo01
@opolyo01
Jun 05 2015 16:31
get: function(filteredDimensions) {
if(filteredDimensions){
return filteredDimensions;
}
else{//logic for returning original set of dimensions
Basically, I have search that filters for the list of dimensions to show
Chris Gomez
@akagomez
Jun 05 2015 16:32
The reason I ask is that get is meant to describe a value that is made up of other values. And since that value is dependent on other values, the get function will only be evaluated when one of those dependent values are changed. In other words, map.attr(‘list’) won’t call get because none of its dependent values have changed. However, when you pass a value to the can.compute like this.. map.attr(‘computedProp’, anotherList) the compute re-evaluates due to the new lastSetVal.
Aside: In your original example you do this.scope.dimensionList(). That’s the incorrect way to read the value. What you should do instead is this.scope.attr(‘dimensionList’).
Okay, so you want an initial list, and you’d like to filter it on keyup?
opolyo01
@opolyo01
Jun 05 2015 16:35
yeah
Chris Gomez
@akagomez
Jun 05 2015 16:35
Gotcha.
opolyo01
@opolyo01
Jun 05 2015 16:36
I am thinking to create a searchTerm compute that would be used inside of get for dimensionList
and then change searchTerm inside of the keyUp event
Chris Gomez
@akagomez
Jun 05 2015 16:37
You can define a default with the value method. Provide it a function and it will populate that value for all new instances of the map if one isn’t passed when calling new.. new CustomMap(props).
That’s not a bad idea either.
opolyo01
@opolyo01
Jun 05 2015 16:38
I am just trying to figure out where to throw this searchTerm variable
in the past I would simply do this.searchTerm = can.compute("")
but with can.Component.. would it belong in my can.Map
Chris Gomez
@akagomez
Jun 05 2015 16:40
Yeah, in your view model.
(or scope if you haven’t made the change)
opolyo01
@opolyo01
Jun 05 2015 16:48
Thanks, it works. Now I need to add "change, blur" on top of keyUp event and I am all set
Chris Gomez
@akagomez
Jun 05 2015 16:51
Great! In the meantime, I put together this demo: http://jsbin.com/vusuzu/1/edit?js,console
I'm currently working on a much easier way to derive a bound, filtered list from another, so stay tuned: https://github.com/canjs/can-derive
opolyo01
@opolyo01
Jun 05 2015 16:54
pretty useful
opolyo01
@opolyo01
Jun 05 2015 17:14
Is it the correct way defining the same handler for multiple events
'.search-dimension keyup': this.searchTermChanged,
'.search-dimension change': this.searchTermChanged,
'.search-dimension blur': this.searchTermChanged,
        searchTermChanged: function(el, ev){
            var searchTerm = el.val();
            this.scope.attr('searchTerm', searchTerm);
        },
somehow it only works only if I do -- '.search-dimension keyup': function(el, ev)
Chris Gomez
@akagomez
Jun 05 2015 17:31
@opolyo01 'el event
Whoops…
’el event’: ‘handler’
opolyo01
@opolyo01
Jun 05 2015 17:31
nice
'.search-dimension keyup': 'searchTermChanged',
'.search-dimension change': 'searchTermChanged',
'.search-dimension blur': 'searchTermChanged',
'.search-dimension search': 'searchTermChanged',
works
Alex
@whitecolor
Jun 05 2015 19:54

is is possible to to like this

{{#each items "item"}}

//refere tho current item as "item", not {.} or this
{{item}}

{{/#item}}

?