Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1.1.6pre - something going wrong with can.computes() in Mustache templates #376

Closed
SteveEisner opened this issue May 2, 2013 · 7 comments
Milestone

Comments

@SteveEisner
Copy link

Just an FYI since the "1.1.6pre" has been pushed to "latest" on the CDN.

In this version only (same code confirmed working when I switch back to 1.1.5) when rendering a model via mustache template, if I reference a can.compute property via {{name}} the context passed into the compute is the global window, rather than the model... Any compute that is trying to use "this" will break.

@justinbmeyer
Copy link
Contributor

Example code/test?

Sent from my iPhone

On May 2, 2013, at 6:03 AM, SteveEisner notifications@github.com wrote:

Just an FYI since the "1.1.6pre" has been pushed to "latest" on the CDN.

In this version only (same code confirmed working when I switch back to 1.1.5) when rendering a model via mustache template, if I reference a can.compute property via {{name}} the context passed into the compute is the global window, rather than the model... Any compute that is trying to use "this" will break.


Reply to this email directly or view it on GitHub.

@SteveEisner
Copy link
Author

@justinbmeyer Sorry, I built a fiddle but I can't get it to repro. http://jsfiddle.net/G34Vf/2/
This models what's going on in my class definition and instance use, but it doesn't break.

So instead I'm attaching a souce & stack example of the break from my production code. I realize that a non-executing example may not be that helpful, but this might at least give you an idea?

In the topmost frame, I'm inside a can.compute and "this" is global/window. In the bottom frame, I'm setting an attr of a can.Observe which has been rendered through a mustache template.

I've confirmed that the same code runs just fine if I switch to 1.1.5 ... I don't think I'm doing anything out of the ordinary, but I have hit other boundary cases before with the same code [issue #218]

Source

//=== template (person.mustache) ======
{{#model}}
  .....  {{name}} .....            <-- name is the can.compute
{{/model}}

//===  top frame (person.js) =====
Person = Model({
  // No class methods
},{
  name: can.compute(function() {
    var first = this.attr('first');        <-- line 7, where the error is in the stack below
        *** Uncaught TypeError: Object [object global] has no method 'attr'  ***
    var last = this.attr('last');
    if (!first) return last;
    if (!last) return first;
    return first + ' ' + last;
  })
});

//===  bottom frame (frame.js) =====
  ...
    setModel: function(model) {
      this.attrs.attr({ model: model });   <--- attrs is the Observe instance that was rendered
      return model;
    }
 ....

Stack

Only the top and bottom frames are user code, the rest are can JS modules, generated template code, or jquery.

Model.name (person.js:7)  <-- in this frame, "this" is global
computed (compute.js:213)
Mustache.resolve (mustache.js:724)
Mustache.get (mustache.js:688)
fn.___v1ew.push.can.view.txt.can.Mustache.txt.fn.___v1ew.push.can.view.txt.can.Mustache.txt.context ((program):1)
getValueAndObserved (compute.js:36)
getValueAndBind (compute.js:98)
computeBinder (compute.js:132)
can.extend.txt (render.js:204)
fn.___v1ew.push.can.view.txt.can.Mustache.txt.fn ((program):1)
Mustache.txt (mustache.js:593)
fn.___v1ew.push.can.view.txt.can.Mustache.txt.context ((program):1)
getValueAndObserved (compute.js:36)
getValueAndBind (compute.js:98)
computeBinder (compute.js:132)
can.extend.txt (render.js:204)
fn ((program):1)
Mustache.render (mustache.js:82)
(anonymous function) (mustache.js:51)
can.Control.render (view.js:77)
v.isFunction.s (jquery-1.8.3.min.js:2)
v.event.dispatch (jquery-1.8.3.min.js:2)
o.handle.u (jquery-1.8.3.min.js:2)
v.event.trigger (jquery-1.8.3.min.js:2)
$.extend.trigger (jquery.js:14)
can.Observe.can.Construct.triggerBatch (observe.js:165)
can.Observe.can.Construct._changes (observe.js:212)
v.isFunction.s (jquery-1.8.3.min.js:2)
v.event.dispatch (jquery-1.8.3.min.js:2)
o.handle.u (jquery-1.8.3.min.js:2)
v.event.trigger (jquery-1.8.3.min.js:2)
$.extend.trigger (jquery.js:14)
(anonymous function) (observe.js:153)
can.each (each.js:17)
can.Observe.can.Construct.stopBatch (observe.js:152)
can.Observe.can.Construct._attrs (observe.js:433)
can.Observe.can.Construct.attr (observe.js:235)
declare.setModel (frame.js:33)

@SteveEisner
Copy link
Author

I went looking for other similar bugs and found #305 -- which happens to be exactly the same model I'm trying to create. When I first made these models, I guess I thought that for a function to work in a mustache rendering, it had to be a can.compute (based on examples?) But I've confirmed that my code works with 1.1.6 now if I simply remove the can.compute() and make the "name" method a simple function.

@justinbmeyer
Copy link
Contributor

You shouldn't do it that way. Closing this issue.

@SteveEisner
Copy link
Author

No need to write out a detailed description in a bug, but I'm curious if you have a link that explains why one shouldn't do it that way -- I got the pattern from a canjs team member's code at: https://forum.javascriptmvc.com/topic/can-compute-crazies

If I want to be able to observe the "name" attribute, how should I build the model instead?

@justinbmeyer
Copy link
Contributor

#305 shows how

@SteveEisner
Copy link
Author

Thanks!

On Tue, May 7, 2013 at 9:41 AM, Justin Meyer notifications@github.comwrote:

#305 #305 shows how


Reply to this email directly or view it on GitHubhttps://github.com//issues/376#issuecomment-17554192
.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants