ManuelDeLeon / viewmodel

MVVM for Meteor
https://viewmodel.org
MIT License
205 stars 23 forks source link

Inheritance Issue #253

Closed Louis-Tian closed 8 years ago

Louis-Tian commented 8 years ago

HTML

<template name="parent">
    <span {{b 'text: name'}}></span>
    {{> child }}
</template>

<template name="child">
    child template
    <span {{b 'text: name'}}></span>
</template>

JS

Template.parent.viewmodel({
    name: 'xxx'
})

OUTPUT

xxx child template

Only the span in the parent template shows up correctly. If I am right, the child template should inherit the name property so the expected output should be xxx child template xxx or am I wrong ?

ManuelDeLeon commented 8 years ago

It's working as designed. For child to "inherit" name you need to pass it to it in the context. On May 12, 2016 7:26 PM, "LoTi" notifications@github.com wrote:

HTML

JS

Template.parent.viewmodel({ name: 'xxx' })

OUTPUT

xxx child template

Only the span in the parent template shows up correctly. If I am right, the child template should inherit the name property so the expected output should be

xxx child template xxx

or am I wrong ?

  • Meteor 1.3.2.4
  • manuel:viewmodel 4.1.4

— You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub https://github.com/ManuelDeLeon/viewmodel/issues/253

fvpDev commented 8 years ago

Like {{> child name=name }}

Louis-Tian commented 8 years ago

If this is by design then it is at odds with how blaze's datacontext inheritance works, isn't it?

I agree, explicit is better than implicit. But there seems to be some inconsistency of how this is treated.

<template name="people">
  {{#each people}}
    {{> person }}
  {{/each}}
</template>

<template name="person">
  <p>
    <button {{b "click: parent.remove(_id)"}}>Remove</button>
    <span {{b "text: name"}}></span>
  </p>
</template>
Template.people.viewmodel({
  remove: function(_id) {
    var indexToRemove = _.findIndex(this.people(), function(person) {
      return person._id === _id;
    });
    this.people().splice(indexToRemove, 1);
  },
  people: [
    { _id: 1, name: "Alan"},
    { _id: 2, name: "Brito"}
  ]
});

This is the inheritance example from the documentation. In this example person template automatically inherits the part of viewmodel it is in without explicitly passing.

ManuelDeLeon commented 8 years ago

In this case the person view model "inherits" all properties from its context. The context is the object being iterated upon (e.g. { _id: 1, name: "Alan"}), so the person view model has _id and name. However it doesn't have the properties of the parent (remove or people).

Louis-Tian commented 8 years ago

Then if apply the same logic, in the first example, the child view model should also "inherits" all properties from its context, which is the entire parent view model, given the child template is not within any each or with helper.

ManuelDeLeon commented 8 years ago

Once again, in your first example the context of the child is nothing (an empty object actually). Inside an each block the context is the item being iterated upon.

Putting that aside, think of what you want in practical terms. It would mean that if you have a view model nested 10 levels below, that view model will have each and every one of the properties from all view models above it. That's a debugging nightmare.