From 178f45b080c42e9def5d3a30c4ab7e99fb38b1dc Mon Sep 17 00:00:00 2001 From: Alfredo Delgado Date: Tue, 24 Mar 2015 11:13:04 -0500 Subject: [PATCH 1/2] Fixing instances of "recieves" in docs. --- model/doc/findAll.md | 2 +- model/doc/findOne.md | 2 +- model/doc/model_destroy.md | 2 +- model/doc/model_save.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/model/doc/findAll.md b/model/doc/findAll.md index bfb9bb79a6f..d6aad4762c7 100644 --- a/model/doc/findAll.md +++ b/model/doc/findAll.md @@ -7,7 +7,7 @@ Retrieve multiple resources from a server. @param {Object} params Values to filter the request or results with. -@param {function(can.Model.List)} [success(list)] A callback to call on successful retrieval. The callback recieves +@param {function(can.Model.List)} [success(list)] A callback to call on successful retrieval. The callback receives a can.Model.List of the retrieved resources. @param {function(can.AjaxSettings)} [error(xhr)] A callback to call when an error occurs. The callback receives the XmlHttpRequest object. diff --git a/model/doc/findOne.md b/model/doc/findOne.md index f779a8fcff6..f24b4be6c88 100644 --- a/model/doc/findOne.md +++ b/model/doc/findOne.md @@ -8,7 +8,7 @@ Retrieve a single instance from the server. @param {Object} params Values to filter the request or results with. -@param {function(can.Model)} [success(model)] A callback to call on successful retrieval. The callback recieves +@param {function(can.Model)} [success(model)] A callback to call on successful retrieval. The callback receives the retrieved resource as a can.Model. @param {function(can.AjaxSettings)} [error(xhr)] A callback to call when an error occurs. The callback receives the XmlHttpRequest object. diff --git a/model/doc/model_destroy.md b/model/doc/model_destroy.md index 0fb812cae02..7aa6e6eaf56 100644 --- a/model/doc/model_destroy.md +++ b/model/doc/model_destroy.md @@ -2,7 +2,7 @@ @parent can.Model.prototype @description Destroy a Model on the server. @signature `model.destroy([success[, error]])` -@param {function} [success] A callback to call on successful destruction. The callback recieves +@param {function} [success] A callback to call on successful destruction. The callback receives the can.Model as it was just prior to destruction. @param {function} [error] A callback to call when an error occurs. The callback receives the XmlHttpRequest object. diff --git a/model/doc/model_save.md b/model/doc/model_save.md index 1a10b1d1768..80ea34fb6d4 100644 --- a/model/doc/model_save.md +++ b/model/doc/model_save.md @@ -2,7 +2,7 @@ @parent can.Model.prototype @description Save a model back to the server. @signature `model.save([success[, error]])` -@param {function} [success] A callback to call on successful save. The callback recieves +@param {function} [success] A callback to call on successful save. The callback receives the can.Model after saving. @param {function} [error] A callback to call when an error occurs. The callback receives the XmlHttpRequest object. From 79fc76ff2d9b09bd85a949cd3422a7467c109b84 Mon Sep 17 00:00:00 2001 From: Justin Meyer Date: Wed, 25 Mar 2015 09:18:50 -0500 Subject: [PATCH 2/2] making viewModel be used everywhere --- component/component.js | 20 +-------- component/component_test.js | 22 +++++----- component/examples/2.html | 4 +- component/examples/accordion.html | 6 +-- component/examples/click_me.html | 2 +- component/examples/grid.js | 8 ++-- component/examples/hello-world.html | 2 +- component/examples/paginate.html | 14 +++---- component/examples/paginate_events_next.html | 2 +- .../paginate_events_next_update_page.html | 4 +- component/examples/tabs.html | 24 +++++------ component/scope.md | 5 +++ component/view-model.md | 15 +++---- guides/recipes.md | 42 +++++++++---------- util/can.js | 24 ++++++----- view/autorender/autorender.js | 2 +- view/autorender/autorender.md | 14 +++---- view/autorender/tests/requirejs-basics.html | 2 +- view/autorender/tests/steal-basics.html | 2 +- 19 files changed, 100 insertions(+), 114 deletions(-) create mode 100644 component/scope.md diff --git a/component/component.js b/component/component.js index fc38500e409..7e9a3c18b22 100644 --- a/component/component.js +++ b/component/component.js @@ -235,6 +235,7 @@ steal("can/util", "can/view/callbacks","can/control", "can/observe", "can/view/m // Set `componentScope` to `this.viewModel` and set it to the element's `data` object as a `viewModel` property this.scope = this.viewModel = componentScope; can.data(can.$(el), "scope", this.scope); + can.data(can.$(el), "viewModel", this.scope); // Create a real Scope object out of the viewModel property var renderedScope = lexicalContent ? @@ -482,24 +483,7 @@ steal("can/util", "can/view/callbacks","can/control", "can/observe", "can/view/m */ // Define the `can.viewModel` function that can be used to retrieve the // `viewModel` from the element - can.scope = can.viewModel = function (el, attr, val) { - el = can.$(el); - var scope = can.data(el, "scope"); - if(!scope) { - scope = new can.Map(); - can.data(el, "scope", scope); - } - switch (arguments.length) { - case 0: - case 1: - return scope; - case 2: - return scope.attr(attr); - default: - scope.attr(attr, val); - return el; - } - }; + var $ = can.$; diff --git a/component/component_test.js b/component/component_test.js index 1323a3efcc6..8f20824b807 100644 --- a/component/component_test.js +++ b/component/component_test.js @@ -60,7 +60,7 @@ steal("can/component", "can/view/stache" ,"can/route", "steal-qunit", function ( "{{/panels}}" + "" + "", - scope: { + viewModel: { panels: [], addPanel: function (panel) { @@ -104,21 +104,21 @@ steal("can/component", "can/view/stache" ,"can/route", "steal-qunit", function ( // make sure works template: "{{#if active}}{{/if}}", tag: "panel", - scope: { + viewModel: { active: false, title: "@" }, events: { " inserted": function () { - can.scope(this.element[0].parentNode) - .addPanel(this.scope); + can.viewModel(this.element[0].parentNode) + .addPanel(this.viewModel); }, " removed": function () { - if (!can.scope(this.element[0].parentNode)) { + if (!can.viewModel(this.element[0].parentNode)) { console.log("bruke"); } - can.scope(this.element[0].parentNode) - .removePanel(this.scope); + can.viewModel(this.element[0].parentNode) + .removePanel(this.viewModel); } } }); @@ -678,13 +678,13 @@ steal("can/component", "can/view/stache" ,"can/route", "steal-qunit", function ( can.append(can.$("#qunit-fixture"), can.view.mustache("")()); var el = can.$("my-taggy-tag"); - equal(can.viewModel(el), can.data(el, "scope"), "one argument grabs the viewModel object"); + equal(can.viewModel(el), can.data(el, "viewModel"), "one argument grabs the viewModel object"); equal(can.viewModel(el, "foo"), "bar", "two arguments fetches a value"); can.viewModel(el, "foo", "baz"); equal(can.viewModel(el, "foo"), "baz", "Three arguments sets the value"); if (window.$ && $.fn) { el = $("my-taggy-tag"); - equal(el.viewModel(), can.data(el, "scope"), "jQuery helper grabs the viewModel object"); + equal(el.viewModel(), can.data(el, "viewModel"), "jQuery helper grabs the viewModel object"); equal(el.viewModel("foo"), "baz", "jQuery helper with one argument fetches a property"); equal(el.viewModel("foo", "bar").get(0), el.get(0), "jQuery helper returns the element"); equal(el.viewModel("foo"), "bar", "jQuery helper with two arguments sets the property"); @@ -703,7 +703,7 @@ steal("can/component", "can/view/stache" ,"can/route", "steal-qunit", function ( var el = can.$("#me"); var viewModel = can.viewModel(el); ok(!!viewModel, "viewModel created where it didn't exist."); - equal(viewModel, can.data(el, "scope"), "viewModel is in the data."); + equal(viewModel, can.data(el, "viewModel"), "viewModel is in the data."); }); test('setting passed variables - two way binding', function () { @@ -1455,7 +1455,7 @@ steal("can/component", "can/view/stache" ,"can/route", "steal-qunit", function ( ok(state.attr('product') == null, 'product was removed'); }); - test('changing viewModel property rebinds {scope.<...>} events (#1529)', 2, function(){ + test('changing viewModel property rebinds {viewModel.<...>} events (#1529)', 2, function(){ can.Component.extend({ tag: 'rebind-viewmodel', events: { diff --git a/component/examples/2.html b/component/examples/2.html index 3fa9c40457e..67c70f92505 100644 --- a/component/examples/2.html +++ b/component/examples/2.html @@ -1,4 +1,4 @@ - diff --git a/component/examples/click_me.html b/component/examples/click_me.html index ea6e79fc45b..6f593acd3d0 100644 --- a/component/examples/click_me.html +++ b/component/examples/click_me.html @@ -12,7 +12,7 @@ }, events: { click: function(){ - this.scope.attr("visible", !this.scope.attr("visible") ); + this.viewModel.attr("visible", !this.viewModel.attr("visible") ); } } }); diff --git a/component/examples/grid.js b/component/examples/grid.js index e4239136cd3..85bd9f6c79e 100644 --- a/component/examples/grid.js +++ b/component/examples/grid.js @@ -10,17 +10,17 @@ can.Component.extend({ }, '{deferreddata} change': 'update', update: function () { - var deferred = this.scope.attr('deferreddata'), - scope = this.scope; + var deferred = this.viewModel.attr('deferreddata'), + viewModel = this.viewModel; if (can.isDeferred(deferred)) { this.element.find('tbody') .css('opacity', 0.5); deferred.then(function (items) { - scope.attr('items') + viewModel.attr('items') .attr(items, true); }); } else { - scope.attr('items') + viewModel.attr('items') .attr(deferred, true); } }, diff --git a/component/examples/hello-world.html b/component/examples/hello-world.html index 74554c19816..4364158c43e 100644 --- a/component/examples/hello-world.html +++ b/component/examples/hello-world.html @@ -17,7 +17,7 @@ }, events: { click: function(){ - this.scope.attr("visible", true) + this.viewModel.attr("visible", true) } } }); diff --git a/component/examples/paginate.html b/component/examples/paginate.html index 151dd7def6a..afc27a40dd7 100644 --- a/component/examples/paginate.html +++ b/component/examples/paginate.html @@ -168,23 +168,23 @@ init: function () { this.update(); }, - "{scope} deferreddata": "update", + "{viewModel} deferreddata": "update", update: function () { - var deferred = this.scope.attr('deferreddata'), - scope = this.scope, + var deferred = this.viewModel.attr('deferreddata'), + viewModel = this.viewModel, el = this.element; if (can.isDeferred(deferred)) { - this.scope.attr("waiting", true); + this.viewModel.attr("waiting", true); this.element.find('tbody').css('opacity', 0.5); deferred.then(function (items) { - scope.attr('items').replace(items); + viewModel.attr('items').replace(items); }); } else { - scope.attr('items').attr(deferred, true); + viewModel.attr('items').attr(deferred, true); } }, "{items} change": function () { - this.scope.attr("waiting", false); + this.viewModel.attr("waiting", false); this.element.find('tbody').css('opacity', 1); } } diff --git a/component/examples/paginate_events_next.html b/component/examples/paginate_events_next.html index 3cd2b34a548..ad2f48e628c 100644 --- a/component/examples/paginate_events_next.html +++ b/component/examples/paginate_events_next.html @@ -19,7 +19,7 @@ template: "Page {{page}} ", events: { ".next click": function(){ - this.scope.next(); + this.viewModel.next(); } } }) diff --git a/component/examples/paginate_events_next_update_page.html b/component/examples/paginate_events_next_update_page.html index 851a9025167..65bf7c7e8d4 100644 --- a/component/examples/paginate_events_next_update_page.html +++ b/component/examples/paginate_events_next_update_page.html @@ -19,10 +19,10 @@ template: "Page 1 ", events: { ".next click": function(){ - this.scope.next(); + this.viewModel.next(); }, "{scope} offset": function(){ - this.element.find("span").text( this.scope.page() ) + this.element.find("span").text( this.viewModel.page() ) } } }) diff --git a/component/examples/tabs.html b/component/examples/tabs.html index 4182d165176..d1f97403478 100644 --- a/component/examples/tabs.html +++ b/component/examples/tabs.html @@ -51,7 +51,7 @@ tag: "tabs", template: "
    "+ - // Create an LI for each item in the panel's scope object + // Create an LI for each item in the panel's viewModel object "{{#panels}}"+ "
  • "+ @@ -65,7 +65,7 @@ // tabs element. panels: [], // When a `` element is inserted into the document, - // it calls this method to add the panel's scope to the + // it calls this method to add the panel's viewModel to the // panels array. addPanel: function(panel){ // If this is the first panel, activate it. @@ -75,7 +75,7 @@ this.attr("panels").push(panel); }, // When a `` element is removed from the document, - // it calls this method to remove the panel's scope from + // it calls this method to remove the panel's viewModel from // the panels array. removePanel: function(panel){ var panels = this.attr("panels"); @@ -95,12 +95,12 @@ this.attr("active",panel); this.attr("panels").each(function(panel){ panel.attr("active", false) - }) + }); panel.attr("active",true); }, - // this is scope, not mustache - // consider removing scope as arg + // this is viewModel, not mustache + // consider removing viewModel as arg isActive: function( panel ) { return this.attr('active') == panel } @@ -116,19 +116,19 @@ }, events: { inserted: function(){ - this.element.parent().scope().addPanel( this.scope ); + this.element.parent().viewModel().addPanel( this.viewModel ); }, removed: function(){ - this.element.parent().scope().removePanel( this.scope ); + this.element.parent().viewModel().removePanel( this.viewModel ); } } -}) +}); var foodTypes= new can.List([ {title: "Fruits", content: "oranges, apples"}, {title: "Breads", content: "pasta, cereal"}, {title: "Sweets", content: "ice cream, candy"} -]) +]); window.foodTypes = foodTypes; $("#out").html( can.view("app",{ @@ -139,9 +139,9 @@ content: "Carrots, peas, kale" }) } -})) +})); -}) +}); diff --git a/component/scope.md b/component/scope.md new file mode 100644 index 00000000000..cc247c6c456 --- /dev/null +++ b/component/scope.md @@ -0,0 +1,5 @@ +@property {*} can.Component.prototype.scope +@parent can.Component.prototype + +@deprecated {2.2} In 2.2 `scope` has been renamed to [can.Component::viewModel] to avoid confusion with [can.view.Scope]. `scope` is still available for backwards compatibility. + diff --git a/component/view-model.md b/component/view-model.md index b340bdbc78f..553ff318aba 100644 --- a/component/view-model.md +++ b/component/view-model.md @@ -1,24 +1,19 @@ -@property {Object|can.Map|function} can.Component.prototype.scope -@parent can.Component.prototype - -Provides or describes a [can.Map] constructor function or `can.Map` instance that will be -used to retrieve values found in the component's [can.Component::template template]. - -@deprecated In 2.2 `scope` has been renamed to [can.Component::viewModel] to avoid confusion with [can.view.Scope]. `scope` is still available for backwards compatibility. - - @property {Object|can.Map|function} can.Component.prototype.viewModel @parent can.Component.prototype +@description + Provides or describes a [can.Map] constructor function or `can.Map` instance that will be used to retrieve values found in the component's [can.Component::template template]. The map instance is initialized with values specified by the component element's attributes. -__Node:__ In 2.1, [can.stache] and [can.mustache] pass values to the +__Note:__ In 2.1, [can.stache] and [can.mustache] pass values to the viewModel differently. To pass data from the viewModel, you must wrap your attribute value with `{}`. In 3.0, `can.mustache` will use `can.stache`'s syntax. + + @option {Object} A plain JavaScript object that is used to define the prototype methods and properties of [can.Construct constructor function] that extends [can.Map]. For example: diff --git a/guides/recipes.md b/guides/recipes.md index 0a969a6d767..a7d76c3a22c 100644 --- a/guides/recipes.md +++ b/guides/recipes.md @@ -390,10 +390,10 @@ appears in a template. can.Component.extend({ tag: 'people', -The `scope` object on a `Component` contains the component's state, data, +The `viewModel` object on a `Component` contains the component's state, data, and behavior. Here, it specifies how to `remove` a person from the list: - scope: { + viewModel: { people: people, remove: function( person ) { var people = this.attr("people"); @@ -407,10 +407,10 @@ The template for the component itself is passed via the `template` property. This can either be an external file or a string. Each `li` uses `can-click`, [which declares an event binding.](http://canjs.com/docs/can.view.bindings.can-EVENT.html) Here, `remove` inside the component's -scope will be called with the relevant `people` object +viewModel will be called with the relevant `people` object as an argument. - scope: { + viewModel: { template: '
      ' + '{{#each people}}' + '
    • ' + @@ -446,7 +446,7 @@ This is one of the most useful features of components. ### Tabs Widget Behavior Before implementing the component itself, we'll -define an observable *view model*--the `scope` object +define an observable *view model*--the `viewModel` object of the UI element. This makes the code modular and easier to manage (and also allows for unit testing). @@ -512,13 +512,13 @@ For this component, our template should look something like this: A designer can create a `tabs` component with `panel` components inside it. -The `template` object on the tabs component's scope needs to be able to render +The `template` object on the tabs component's viewModel needs to be able to render the content that is inside of the `` tag. To do this, we simply use the `` tag, which will render everything within the component's tags: can.Component.extend({ tag: "tabs", - scope: TabsViewModel, + viewModel: TabsViewModel, template: "
        \ {{#each panels}}\
      • {{title}}
      • \ @@ -532,20 +532,20 @@ as components. The tabs template contains the logic for whether the panel is visible (`visible` is controlled by the tabs component's `activate` method). -Each panel's `scope` contains a title, which should be +Each panel's `viewModel` contains a title, which should be taken from the `title` attribute in the `` tag. If you want to set the string value of a Component's -attribute as a `scope` variable, use `@'`. +attribute as a `viewModel` variable, use `@'`. can.Component.extend({ tag: "panel", template: "{{#if visible}}{{/if}}", - scope: { + viewModel: { title: "@" }, ... -In addition to the `scope` property, a component has an +In addition to the `viewModel` property, a component has an [`events` property](http://canjs.com/docs/can.Component.prototype.events.html). This `events` property uses a `can.Control` instantiated inside the component to handle events. @@ -553,16 +553,16 @@ the component to handle events. Since we defined behavior for adding panels on the parent `tabs` component, we should use this method whenever a `panel` is inserted into the page (and an `inserted` event is triggered). -To add the panel to the `tabs` component's scope, we call the -`addPanel` method by accessing the parent scope with `this.element.parent().scope()`: +To add the panel to the `tabs` component's view model, we call the +`addPanel` method by accessing the parent view model with `this.element.parent().viewModel()`: ... events: { inserted: function() { - this.element.parent().scope().addPanel( this.scope ) + this.element.parent().viewModel().addPanel( this.viewModel ) }, removed: function() { - this.element.parent().scope().addPanel( this.scope ) + this.element.parent().viewModel().addPanel( this.viewModel ) } } }); @@ -607,14 +607,14 @@ from `can.Model` to fetch the messages and create new ones: create : 'POST ' + myServerUrl + '/messages' },{}); -In a chat component's scope, we will use the `Message` model to +In a chat component's viewModel, we will use the `Message` model to save new messages and observe changes to the Model. [`new Message.List({})`](http://canjs.com/docs/can.Model.List.html#sig_newcan_Model_List__models__) is a shortcut to perform the [`findAll`](http://canjs.com/docs/can.Model.findAll.html) operation on a `can.Model` and return a `can.List`. ... - scope: { + viewModel: { messages: new Message.List({}), newMessage: "" ... @@ -625,7 +625,7 @@ Since this chat application uses a `
        ` for sending messages, we'll use There's one more helper used in the template: [`can-value`](http://canjs.com/docs/can.view.bindings.can-value.html). This automatically two-way binds the value of an input field to an observable -property on the `scope` of the component (in this case, `newMessage`). +property on the `viewModel` of the component (in this case, `newMessage`). can.Component.extend({ tag: 'chat', @@ -650,7 +650,7 @@ the Component's `newMessage` attribute when a user submits the form. To save the new message to the server, call `save()`. - submitMessage: function(scope, el, ev){ + submitMessage: function(context, el, ev){ ev.preventDefault(); new Message({body: this.attr("newMessage")}).save(); this.attr("newMessage", ""); @@ -661,7 +661,7 @@ must be updated. events: { '{Message} created': function(construct, ev, message){ - this.scope.attr('messages').push(message); + this.viewModel.attr('messages').push(message); } } @@ -670,7 +670,7 @@ or from another user. In the next section, we demonstrate how to use [socket.io](http://socket.io/) to update the `Message` model with messages from other users in real time. Binding to the `created` event for **all** messages allows us to create a single entry point that pushes new messages -to the `scope`, [regardless of where those messages are from.](http://canjs.com/docs/can.Model.html#section_Listentochangesindata) +to the `viewModel`, [regardless of where those messages are from.](http://canjs.com/docs/can.Model.html#section_Listentochangesindata) When the chat Component is loaded, messages are loaded from the server using `can.Model` and `new Message.List({})`. When a new message is diff --git a/util/can.js b/util/can.js index 76fb7ba26da..c6f767c0ce7 100644 --- a/util/can.js +++ b/util/can.js @@ -70,21 +70,23 @@ steal(function () { }; // Define the `can.scope` function that can be used to retrieve the `scope` from the element - can.scope = function (el, attr) { + can.scope = can.viewModel = function (el, attr, val) { el = can.$(el); - // if scope doesn't exist, create it - var scope = can.data(el, "scope"); + var scope = can.data(el, "scope") || can.data(el, "viewModel"); if(!scope) { - scope = can.Map ? new can.Map() : {}; + scope = new can.Map(); can.data(el, "scope", scope); + can.data(el, "viewModel", scope); } - - // If `attr` is passed to the `can.scope` function return the value of that - // attribute on the `scope` object otherwise return the whole scope - if (attr) { - return scope.attr(attr); - } else { - return scope; + switch (arguments.length) { + case 0: + case 1: + return scope; + case 2: + return scope.attr(attr); + default: + scope.attr(attr, val); + return el; } }; diff --git a/view/autorender/autorender.js b/view/autorender/autorender.js index 2013816368b..9560bc3ee01 100644 --- a/view/autorender/autorender.js +++ b/view/autorender/autorender.js @@ -39,7 +39,7 @@ steal("can/util",function(can){ } } function setupScope(el) { - var scope = can.scope(el); + var scope = can.viewModel(el); can.each(el.attributes||[], function(attr) { setAttr(el, attr.name, scope); diff --git a/view/autorender/autorender.md b/view/autorender/autorender.md index a219f1ac1b9..4281f912536 100644 --- a/view/autorender/autorender.md +++ b/view/autorender/autorender.md @@ -43,8 +43,8 @@ For example, you might have a page like: // Wait until everything has rendered. can.autorender(function(){ - // Update the scope the template was rendred with: - $("#main").scope().attr("message","Rendered!"); + // Update the viewModel the template was rendred with: + $("#main").viewModel().attr("message","Rendered!"); }) @@ -133,7 +133,7 @@ Becomes: The template is rendered with a [can.Map] made from the attributes of the template source element. That `map` is available on the -template source element via [can.scope]. You can +template source element via [can.viewModel]. You can change the map at any time: ``` @@ -142,14 +142,14 @@ change the map at any time: {{message}}! ``` You can change attributes on the element and it will update the -scope too: +viewModel too: ``` @@ -198,7 +198,7 @@ For demo pages that require a little custom setup: diff --git a/view/autorender/tests/requirejs-basics.html b/view/autorender/tests/requirejs-basics.html index 42eb51c295a..d0d348c26ae 100644 --- a/view/autorender/tests/requirejs-basics.html +++ b/view/autorender/tests/requirejs-basics.html @@ -23,7 +23,7 @@ require(['can/view/autorender'],function(ready){ ready(function() { - isReady($("body my-component"), can.scope('my-component')); + isReady($("body my-component"), can.viewModel('my-component')); }, hasError); }); diff --git a/view/autorender/tests/steal-basics.html b/view/autorender/tests/steal-basics.html index b8c49e30305..a1ea2c2c3e4 100644 --- a/view/autorender/tests/steal-basics.html +++ b/view/autorender/tests/steal-basics.html @@ -16,7 +16,7 @@