UNPKG

can

Version:

MIT-licensed, client-side, JavaScript framework that makes building rich web applications easy.

541 lines (386 loc) 15.3 kB
<!DOCTYPE html> <!--#################################################################### THIS IS A GENERATED FILE -- ANY CHANGES MADE WILL BE OVERWRITTEN INSTEAD CHANGE: source: [object Object] @page guides/pmo/Components ######################################################################## --> <html lang="en"> <head> <meta charset="utf-8"> <title>CanJS - Components</title> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <link rel="stylesheet" type="text/css" href="../../static/bundles/bit-docs-site/static.css"> <link rel="shortcut icon" sizes="16x16 24x24 32x32 48x48 64x64" href="/docs/images/canjs_favicon.ico"> <link rel="apple-touch-icon" sizes="57x57" href="../../../docs/images/canjs_favicon_57x57.png"> <link rel="apple-touch-icon-precomposed" sizes="57x57" href="../../../docs/images/canjs_favicon_57x57.png"> <link rel="apple-touch-icon" sizes="72x72" href="../../../docs/images/canjs_favicon_72x72.png"> <link rel="apple-touch-icon" sizes="114x114" href="../../../docs/images/canjs_favicon_114x114.png"> <link rel="apple-touch-icon" sizes="120x120" href="../../../docs/images/canjs_favicon_128x128.png"> <link rel="apple-touch-icon" sizes="144x144" href="../../../docs/images/canjs_favicon_144x144.png"> <link rel="apple-touch-icon" sizes="152x152" href="../../../docs/images/canjs_favicon_152x152.png"> <meta content="yes" name="apple-mobile-web-app-capable"> <meta name="apple-mobile-web-app-status-bar-style" content="white-translucent"> <script> (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-2302003-11', 'auto'); ga('send', 'pageview'); </script> </head> <body> <input type="checkbox" id="nav-trigger" class="nav-trigger"/> <label for="nav-trigger">Menu</label> <div id="everything"> <div id="left" class="column"> <div class="top-left"> <div class="brand"> <div class="logo"> <a href="../../../index.html" alt="CanJS"></a> <div class="dropdown project-dropdown"> <a href="https://donejs.com/">DoneJS</a> <a href="http://stealjs.com/">StealJS</a> <a href="http://jquerypp.com/">jQuery ++</a> <a href="https://funcunit.com/">FuncUnit</a> <a href="http://documentjs.com/">DocumentJS</a> </div> </div> <div class="version"> <div class="version-number"> 3.0.0 </div> <div class="dropdown version-dropdown"> <a href="https://v2.canjs.com">2.3.27</a> </div> </div> </div> <div class="search-bar"> <p> &nbsp; </p> </div> </div> <div class="bottom-left"> <div class="social-side-container"> <ul class="social-side"> <li> <a class="header-mobile github" href="https://github.com/canjs/canjs" target="_blank"><img class="social-icon-small" src="../../../docs/images/github.png">Github</a> </li> <li> <a class="header-mobile twitter" href="https://twitter.com/canjs" target="_blank"><img class="social-icon-small" src="../../../docs/images/twitter.png">Twitter</a> </li> </ul> <ul class="social-side"> <li> <a class="header-mobile" href="https://gitter.im/canjs/canjs" target="_blank">Chat</a> </li> <li> <a class="header-mobile" href="http://forums.donejs.com/c/canjs" target="_blank">Forum</a> </li> </ul> </div> <ul> <li class="current parent expanded"> <a class="page" href="Components.html" title=""> Components </a> </li> <li class=" "> <a class="page" href="ApplicationDesign.html" title=""> Application Design </a> </li> <li class=" "> <a class="page" href="../../pmo/Setup.html" title=""> Setup </a> </li> <li class=" "> <a class="page" href="Constructors.html" title=""> Constructors </a> </li> <li class=" "> <a class="page" href="TheDefinePlugin.html" title=""> The Define Plugin </a> </li> <li class=" "> <a class="page" href="StacheTemplates.html" title=""> Stache Templates </a> </li> <li class=" "> <a class="page" href="AppStateAndRouting.html" title=""> App State and Routing </a> </li> <li class=" "> <a class="page" href="Observables.html" title=""> Observables </a> </li> <li class=" "> <a class="page" href="ViewModels.html" title=""> View Models </a> </li> <li class=" "> <a class="page" href="DataModelsAndFixtures.html" title=""> Data Models and Fixtures </a> </li> <li class=" "> <a class="page" href="LoadingStates.html" title=""> Loading States </a> </li> <li class=" "> <a class="page" href="EventHandling.html" title=""> Event Handling </a> </li> <li class=" "> <a class="page" href="WebServiceCommunication.html" title=""> Web Service Communication </a> </li> <li class=" "> <a class="page" href="Recap.html" title=""> Recap </a> </li> </ul> </div> </div> <div id="right" class="column"> <div class="top-right"> <div class="top-right-top"> <ul class="top-right-bitovi"> <li class="dropdown"> <a href="http://bitovi.com" class="bitovi icon-bits">Bitovi</a> <ul class="dropdown-menu"> <li><a href="http://bitovi.com">Bitovi.com</a></li> <li><a href="http://bitovi.com/blog/">Blog</a></li> <li><a href="http://bitovi.com/consulting/">Consulting</a></li> <li><a href="http://bitovi.com/training/">Training</a></li> <li><a href="http://bitovi.com/open-source/">Open Source</a></li> </ul> </li> </ul> <div class="brand"> <div class="logo"> <a href="../../../index.html" alt="CanJS"></a> </div> </div> <ul class="top-right-links"> <li> <a href="https://gitter.im/canjs/canjs">Chat</a> </li> <li> <a href="http://forums.donejs.com/c/canjs">Forum</a> </li> <li> <a class="github-button nav-social" href="https://github.com/canjs/canjs" data-count-href="/canjs/canjs/stargazers" data-count-api="/repos/canjs/canjs#stargazers_count">Star</a> </li> <li> <a href="https://twitter.com/canjs" class="twitter-follow-button nav-social" data-show-count="true" data-show-screen-name="false">Follow @canjs</a><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script> </li> </ul> </div> <div class="breadcrumb"> <li><a href="../pmo.html">Place My Order Guide</a></li> / <li><a href="Components.html">Components</a></li> <li class="breadcrumb-dropdown">/ <a> On this page</a> <ul class="on-this-page"></ul> </li> <div class="nav-toggle" title="Back to top"></div> </div> </div> <div class="bottom-right"> <article> <section class="title"> <div class="page-type"> <h1>Components</h1> <div>page</div> </div> <section class="description"> </section> </section> <section class="on-this-page-table"> </section> <section class="title-footer"> <ul class="title-links"> <!-- <li><a href="#">docco</a></li> --> <li><a href="//github.com/canjs/canjs/tree/v3.0.0/docs/can-guides/experiment/pmo/components.md">source</a></li> <!-- <li><a href="#">download</a></li> --> <!-- <li><a href="#">tests</a></li> --> </ul> </section> <section class="body"> <div class="getting-started"> <hr /> <p><strong>In this Chapter</strong></p> <ul> <li>First <code>can.Component</code></li> <li>Auto Instantiation</li> <li>Anatomy of a <code>can.Component</code></li> </ul> <p>Get the code for: <a href="/guides/examples/PlaceMyOrder/ch-4_canjs-getting-started.zip">chapter: components</a></p> <hr /> <p><a name="first-component"></a></p> <h2>First can.Component</h2> <p>If you recall from the introduction, a <a href="../docs/can.Component.html"><code>can.Component</code></a> is like a self-contained, mini web application; in other words, it’s encapsulated. Because <code>can.Component</code>’s are encapsulated, they should each contain their own:</p> <ul> <li>View template file (.stache file)</li> <li>JavaScript file</li> <li>CSS file</li> </ul> <p>This is why we created a <code>components</code> folder for our app&mdash;instead of, say, a <code>js</code> folder. Each component we develop will be in a folder that contains all the files that support that component. This makes components portable, enabling you to reuse them across projects. It also isolates them, making them easier to test and maintain.</p> <p>Put the following code inside <code>components/restaurant_list/restaurant_list.js</code>:</p> <pre><code>can.Component.extend({ tag: 'pmo-restaurant-list', template: can.view('components/restaurant_list/restaurant_list.stache'), viewModel: { currentRestaurant: 'Hello Restaurant Customer' } }); </code></pre> <p>Add the following code to <code>components/restaurant_list/restaurant_list.stache</code>:</p> <pre><code>&lt;h1&gt;{{currentRestaurant}}&lt;/h1&gt; </code></pre> <p>Finally, we need to add a reference to <code>components/restaurant_list/restaurant_list.js</code> in the index.html file. Find this line:</p> <pre><code>&lt;!-- Replace with restaurant list component script --&gt; </code></pre> <p>and replace it with this line:</p> <pre><code>&lt;script src=&quot;components/restaurant_list/restaurant_list.js&quot;&gt;&lt;/script&gt; </code></pre> <p>Now, go back out to your app in the browser and refresh it. On the Restaurants page, you should see it printing: &quot;Hello Restaurant Customer&quot;.</p> <p><img src="../can/guides/images/components/HelloRestaurantCustomer.png" alt="Hello Restaurant Customer message" /></p> <h3>Auto Instantiation</h3> <p>If you recall from <a href="Constructors.html">our previous discussion regarding <code>can.Construct</code></a>, whenever you declare an object using <code>can.Construct</code>, it must be instantiated. Normally, you would either directly instantiate objects using the <code>new</code> keyword, or pass the constructor to an object that would create instances of it. <em><code>can.Component</code> is an exception.</em></p> <p>All we have to do is declare the <code>can.Component</code> using its <code>extend</code> function. Once you declare your <code>can.Component</code>, you’ve registered your component with CanJS. When CanJS parses the <code>main.stache</code> file and encounters the <code>&lt;pmo-restaurant-list&gt;</code> tag, it will automatically instantiate the <code>can.Component</code> associated with it, generate the component’s view inside of its custom tag, and bind that view to your component’s scope.</p> <h3>Basic Anatomy of a can.Component</h3> <p>The <code>can.Component</code> we created above had three properties.</p> <ul> <li><a href="#tag">tag</a>,</li> <li><a href="#template">template</a>, and</li> <li><a href="#viewmodel">viewModel</a></li> </ul> <pre><code>can.Component.extend({ tag: 'pmo-restaurant-list', template: can.view('components/restaurant_list/restaurant_list.stache'), viewModel: { currentRestaurant: 'Hello Restaurant Customer' } }); </code></pre> <p><a name="tag"></a></p> <h4>The “tag” Property</h4> <p>The <code>can.Component</code>’s <code>tag</code> property associates that <code>can.Component</code> with a specific, custom HTML tag.</p> <p>As mentioned above, when the template containing the <code>can.Component</code>’s tag is parsed, the <code>can.Component</code> is instantiated and the contents of its rendered template are inserted as the HTML contents of the custom tag.</p> <p><a name="template"></a></p> <h4>Template</h4> <p>The <code>template</code> property of the <code>can.Component</code> contains the string value of the <code>can.Component</code>’s template. Note that the template property just contains a string value. You can inline the template, if it is small. However, the recommended way of working with templates, to maintain separation of concerns, is to keep them in their own files and load them using <code>can.view</code>, as we have done here.</p> <p><a name="viewmodel"></a></p> <h4>View Model</h4> <p>The <code>viewModel</code> object is the <code>can.Component</code>’s view model. The view model is an abstraction of the view that exposes public properties and functions. Any property or function defined on the view model object is available from the <code>can.Component</code>’s template as either a Stache data key, or a function. In our example above, we created the property <code>currentRestaurant</code> and then referenced it as a Stache data key in our template.</p> <hr /> <p><span class="pull-left"><a href="AppStateAndRouting.html">&lsaquo; App State and Routing</a></span> <span class="pull-right"><a href="ViewModels.html">View Models &rsaquo;</a></span></p> </div> </section> <script type="text/javascript"> var docObject = {"src":{"path":"docs/can-guides/experiment/pmo/components.md"},"description":"\n","name":"guides/pmo/Components","title":"Components","type":"page","parent":"guides/pmo","order":7,"disabletableofcontents":true,"comment":" ","pathToRoot":"../../.."}; </script> </article> <footer><p>CanJS is part of <a href="http://donejs.com" target="_blank">DoneJS</a>. Created and maintained by the core <a href="https://donejs.com/About.html#section=section_Team" target="_blank">DoneJS team</a> and <a href="http://bitovi.com" target="_blank">Bitovi</a>. <strong>Currently 3.0.0.</strong></p></footer> </div> </div> </div> <script> steal = { instantiated: { "bundles/bit-docs-site/static.css!$css" : null } }; </script> <script type='text/javascript' data-main="bit-docs-site/static" src="../../static/node_modules/steal/steal.production.js"></script> <script async defer src="https://buttons.github.io/buttons.js"></script> </body> </html>