Example #1
0
  run(function () {
    bind(root, 'toObject.value1', 'fromObject.value1');
    bind(root, 'toObject.value2', 'fromObject.value2');

    // change both value1 + value2, then  flush bindings.  observer should only
    // fire after bindings are done flushing.
    set(fromObject, 'value1', 'CHANGED');
    set(fromObject, 'value2', 'CHANGED');
  });
Example #2
0
  run(function() {
    a = {
      foo: 'trololol'
    };

    b = {
      a: a
    };
    bind(b, 'foo', 'a.foo');

    c = {
      a: a
    };
    bind(c, 'foo', 'a.foo');
  });
Example #3
0
    run(function() {
      first = EmberObject.create({ output: 'first' });

      second = EmberObject.extend({
        inputDidChange: emberObserver('input', function() {
          set(this, 'output', get(this, 'input'));
        })
      }).create({
        input: 'second',
        output: 'second'
      });

      third = EmberObject.create({ input: 'third' });

      root = { first: first, second: second, third: third };
      binding1 = bind(root, 'second.input', 'first.output');
      binding2 = bind(root, 'second.output', 'third.input');
    });
Example #4
0
    run(function() {
      first = EmberObject.create({ output: 'first' });

      second = EmberObject.createWithMixins({
        input: 'second',
        output: 'second',

        inputDidChange: emberObserver("input", function() {
          set(this, "output", get(this, "input"));
        })
      });

      third = EmberObject.create({ input: "third" });

      root = { first: first, second: second, third: third };
      binding1 = bind(root, 'second.input', 'first.output');
      binding2 = bind(root, 'second.output', 'third.input');
    });
Example #5
0
  init: function() {
    var controller;

    apply(this, this._super, arguments);

    var keywords        = this.templateData.keywords;
    var keywordName     = this.templateHash.keywordName;
    var keywordPath     = this.templateHash.keywordPath;
    var controllerName  = this.templateHash.controller;
    var preserveContext = this.preserveContext;

    if (controllerName) {
      var previousContext = this.previousContext;
      controller = this.container.lookupFactory('controller:'+controllerName).create({
        parentController: previousContext,
        target: previousContext
      });

      this._generatedController = controller;

      if (!preserveContext) {
        this.set('controller', controller);

        this.valueNormalizerFunc = function(result) {
            controller.set('model', result);
            return controller;
        };
      } else {
        var controllerPath = jQuery.expando + guidFor(controller);
        keywords[controllerPath] = controller;
        emberBind(keywords, controllerPath + '.model', keywordPath);
        keywordPath = controllerPath;
      }
    }

    if (preserveContext) {
      emberBind(keywords, keywordName, keywordPath);
    }

  },
Example #6
0
  run(function() {
    a = {};

    defineProperty(a, 'foo', computed(function() {
      getCalled++;
      if (getCalled > 1000) {
        throw 'infinite loop detected';
      }
      return ['foo', 'bar'];
    }));

    b = {
      a: a
    };
    bind(b, 'foo', 'a.foo');
  });
Example #7
0
  run(function() {
    a = {};

    defineProperty(a, 'foo', computed(function(key, value) {
      if (arguments.length === 2) {
        setCalled++;
        setValue = value;
        return value;
      } else {
        getCalled++;
        return setValue;
      }
    }).volatile());

    b = {
      a: a
    };
    bind(b, 'foo', 'a.foo');
  });
Example #8
0
  run(function() {
    a = {};

    defineProperty(a, 'foo', computed({
      get: function(key) {
        getCalled++;
        return setValue;
      },
      set: function(key, value) {
        setCalled++;
        setValue = value;
        return value;
      }
    }).volatile());

    b = {
      a: a
    };
    bind(b, 'foo', 'a.foo');
  });
Example #9
0
/**
  Use the `{{with}}` helper when you want to scope context. Take the following code as an example:

  ```handlebars
  <h5>{{user.name}}</h5>

  <div class="role">
    <h6>{{user.role.label}}</h6>
    <span class="role-id">{{user.role.id}}</span>

    <p class="role-desc">{{user.role.description}}</p>
  </div>
  ```

  `{{with}}` can be our best friend in these cases,
  instead of writing `user.role.*` over and over, we use `{{#with user.role}}`.
  Now the context within the `{{#with}} .. {{/with}}` block is `user.role` so you can do the following:

  ```handlebars
  <h5>{{user.name}}</h5>

  <div class="role">
    {{#with user.role}}
      <h6>{{label}}</h6>
      <span class="role-id">{{id}}</span>

      <p class="role-desc">{{description}}</p>
    {{/with}}
  </div>
  ```

  ### `as` operator

  This operator aliases the scope to a new name. It's helpful for semantic clarity and to retain
  default scope or to reference from another `{{with}}` block.

  ```handlebars
  // posts might not be
  {{#with user.posts as blogPosts}}
    <div class="notice">
      There are {{blogPosts.length}} blog posts written by {{user.name}}.
    </div>

    {{#each post in blogPosts}}
      <li>{{post.title}}</li>
    {{/each}}
  {{/with}}
  ```

  Without the `as` operator, it would be impossible to reference `user.name` in the example above.

  NOTE: The alias should not reuse a name from the bound property path.
  For example: `{{#with foo.bar as foo}}` is not supported because it attempts to alias using
  the first part of the property path, `foo`. Instead, use `{{#with foo.bar as baz}}`.

  ### `controller` option

  Adding `controller='something'` instructs the `{{with}}` helper to create and use an instance of
  the specified controller with the new context as its content.

  This is very similar to using an `itemController` option with the `{{each}}` helper.

  ```handlebars
  {{#with users.posts controller='userBlogPosts'}}
    {{!- The current context is wrapped in our controller instance }}
  {{/with}}
  ```

  In the above example, the template provided to the `{{with}}` block is now wrapped in the
  `userBlogPost` controller, which provides a very elegant way to decorate the context with custom
  functions/properties.

  @method with
  @for Ember.Handlebars.helpers
  @param {Function} context
  @param {Hash} options
  @return {String} HTML string
*/
function withHelper(context, options) {
  if (arguments.length === 4) {
    var keywordName, path, rootPath, normalized, contextPath;

    Ember.assert("If you pass more than one argument to the with helper, it must be in the form #with foo as bar", arguments[1] === "as");
    options = arguments[3];
    keywordName = arguments[2];
    path = arguments[0];

    Ember.assert("You must pass a block to the with helper", options.fn && options.fn !== Handlebars.VM.noop);

    var localizedOptions = o_create(options);
    localizedOptions.data = o_create(options.data);
    localizedOptions.data.keywords = o_create(options.data.keywords || {});

    if (isGlobalPath(path)) {
      contextPath = path;
    } else {
      normalized = normalizePath(this, path, options.data);
      path = normalized.path;
      rootPath = normalized.root;

      // This is a workaround for the fact that you cannot bind separate objects
      // together. When we implement that functionality, we should use it here.
      var contextKey = jQuery.expando + guidFor(rootPath);
      localizedOptions.data.keywords[contextKey] = rootPath;
      // if the path is '' ("this"), just bind directly to the current context
      contextPath = path ? contextKey + '.' + path : contextKey;
    }

    emberBind(localizedOptions.data.keywords, keywordName, contextPath);

    return bind.call(this, path, localizedOptions, true, exists);
  } else {
    Ember.assert("You must pass exactly one argument to the with helper", arguments.length === 2);
    Ember.assert("You must pass a block to the with helper", options.fn && options.fn !== Handlebars.VM.noop);
    return helpers.bind.call(options.contexts[0], context, options);
  }
}
Example #10
0
  run(function() {
    obj = {
      selection: null
    };

    selectionChanged = 0;

    addObserver(obj, 'selection', function () {
      selectionChanged++;
    });

    proto = {
      obj: obj,
      changeSelection: function (value) {
        set(this, 'selection', value);
      }
    };
    bind(proto, 'selection', 'obj.selection');

    a = create(proto);
    b = create(proto);
    rewatch(a);
    rewatch(b);
  });
Example #11
0
 expectDeprecation(() => bind(b, 'foo', 'a.foo'), deprecationMessage);
Example #12
0
 expectDeprecation(() => {
   binding = bind(root, 'toObject.value', 'fromObject.value');
 }, /`Ember\.Binding` is deprecated./);
Example #13
0
 expectDeprecation(() => {
   binding2 = bind(root, 'second.output', 'third.input');
 }, /`Ember\.Binding` is deprecated./);
Example #14
0
 var A = function() {
   bind(this, 'foo', 'bar.baz');
 };
Example #15
0
 expectDeprecation(() => bind(b, 'foo', 'a.foo'), /`Ember.Binding` is deprecated/);
Example #16
0
 run(function () {
   binding = bind(root, 'toObject.value', 'fromObject.value');
 });
Example #17
0
 expectDeprecation(() => {
   bind(c, 'foo', 'a.foo');
 }, deprecationMessage);
Example #18
0
 run(function() {
   bind(foo, 'value', 'bar.value');
 });
Example #19
0
 expectDeprecation(() => {
   bind(foo, 'value', 'bar.value');
 }, deprecationMessage);