Ricerca…
Osservazioni
Gli esempi precedenti di Blaze sono altamente compatibili con la http://bootsnipp.com/ library, che fornisce solo HTML e CSS per i componenti e lascia lo javascript allo sviluppatore. Ciò consente ai componenti di condividere gli stessi metodi di ordinamento, filtraggio, query e cursore sottostanti.
Menu a discesa
Nell'esempio seguente viene creato un menu a discesa Bootstrap, che utilizza solo Blaze e nessun JQuery.
Modello oggetto documento
<nav class="nav navbar-nav">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">{{getSelectedValue}} <span class="glyphicon glyphicon-user pull-right"></span></a>
<ul class="fullwidth dropdown-menu">
<li id="firstOption" class="fullwidth"><a href="#">15 Minutes <span class="glyphicon glyphicon-cog pull-right"></span></a></li>
<li class="divider"></li>
<li id="secondOption"><a href="#">30 Minutes <span class="glyphicon glyphicon-stats pull-right"></span></a></li>
<li class="divider"></li>
<li id="thirdOption"><a href="#">1 Hour <span class="badge pull-right"> 42 </span></a></li>
<li class="divider"></li>
<li id="fourthOption"><a href="#">4 Hour <span class="glyphicon glyphicon-heart pull-right"></span></a></li>
<li class="divider"></li>
<li id="fifthOption"><a href="#">8 Hours <span class="glyphicon glyphicon-log-out pull-right"></span></a></li>
</ul>
</li>
</nav>
Javascript
Template.examplePage.helpers({
getSelectedValue:function(){
return Session.get('selectedValue');
}
});
Template.dropDownWidgetName.events({
'click #firstOption':function(){
Session.set('selectedValue', 1);
},
'click #secondOption':function(){
Session.set('selectedValue', "blue");
},
'click #thirdOption':function(){
Session.set('selectedValue', $('#thirdOption').innerText);
},
'click #fourthOption':function(){
Session.set('selectedValue', Session.get('otherValue'));
},
'click #fifthOption':function(){
Session.set('selectedValue', Posts.findOne(Session.get('selectedPostId')).title);
},
});
Navbars
Un compito molto comune è creare barre di risposta reattive e creare barre di azioni / piè di pagina con controlli diversi in base alla pagina in cui si trova un utente o al ruolo a cui un utente appartiene. Vediamo come eseguire questi controlli.
Router
Router.configure({
layoutTemplate: 'appLayout',
});
Router.route('checklistPage', {
path: '/lists/:_id',
onBeforeAction: function() {
Session.set('selectedListId', this.params._id);
this.next();
},
yieldTemplates: {
'navbarFooter': {
to: 'footer'
}
}
});
Crea un modello di barra di navigazione
<template name="navbarFooter">
<nav id="navbarFooterNav" class="navbar navbar-default navbar-fixed-bottom" role="navigation">
<ul class="nav navbar-nav">
<li><a id="addPostLink"><u>A</u>dd Post</a></li>
<li><a id="editPostLink"><u>E</u>dit Post</a></li>
<li><a id="deletePostLink"><u>D</u>elete Post</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a id="helpLink"><u>H</u>elp</a></li>
</ul>
</nav>
</template>
Definisci i rendimenti nel layout
<template name="appLayout">
<div id="appLayout">
<header id="navbarHeader">
{{> yield 'header'}}
</header>
<div id="mainPanel">
{{> yield}}
</div>
<footer id="navbarFooter" class="{{getTheme}}"">
{{> yield 'footerActionElements' }}
</footer>
</div>
</template>
Modals
Questo follwing è un approccio puramente Blaze che consente di attivare e disattivare gli elementi dell'interfaccia utente. Pensa a questo come una sostituzione per i dialoghi modali. In effetti, esistono diversi modi per implementare finestre di dialogo modali usando questo metodo (è sufficiente aggiungere maschere di background e animazioni).
Modello oggetto documento
<template name="topicsPage">
<div id="topicsPage" class="container">
<div class="panel">
<div class="panel-heading">
Nifty Panel
</div>
<!-- .... -->
<div class="panel-footer">
<!-- step 1. we click on the button object -->
<div id="createTopicButton" class="btn {{ getPreferredButtonTheme }}">Create Topic</div>
</div>
</div>
<!-- step 5 - the handlebars gets activated by the javascript controller -->
<!-- and toggle the creation of new objects in our model -->
{{#if creatingNewTopic }}
<div>
<label for="topicTextInput"></label>
<input id="topicTextInput" value="enter some text..."></input>
<button class="btn btn-warning">Cancel</button>
<button class="btn btn-success">OK</button>
</div>
{{/if}}
</div>
</template>
Javascript
// step 2 - the button object triggers an event in the controller
// which toggles our reactive session variable
Template.topicsPage.events({
'click #createTopicButton':function(){
if(Session.get('is_creating_new topic'){
Session.set('is_creating_new_topic', false);
}else{
Session.set('is_creating_new_topic', true);
}
}
});
// step 0 - the reactive session variable is set false
Session.setDefault('is_creating_new_topic', false);
// step 4 - the reactive session variable invalidates
// causing the creatNewTopic function to be rerun
Template.topicsPage.creatingNewTopic = function(){
if(Session.get('is_creating_new_topic')){
return true;
}else{
return false;
}
}
Tagging
Il livello del database In primo luogo, vogliamo impostare il protocollo di distribuzione dei dati, per assicurarci di poter conservare i dati nel database e scaricarli sul client. È necessario creare tre file ... uno sul server, uno sul client e uno condiviso tra entrambi.
// client/subscriptions.js
Meteor.subscribe('posts');
//lib/model.js
Posts = new Meteor.Collection("posts");
Posts.allow({
insert: function(){
return true;
},
update: function () {
return true;
},
remove: function(){
return true;
}
});
// server.publications.js
Meteor.publish('posts', function () {
return Posts.find();
});
Questo esempio assume il seguente schema del documento per il modello di tagging:
{
_id: "3xHCsDexdPHN6vt7P",
title: "Sample Title",
text: "Lorem ipsum, solar et...",
tags: ["foo", "bar", "zkrk", "squee"]
}
Modello oggetto documento
Secondo, vogliamo creare il nostro modello a oggetti nel livello dell'applicazione. Il seguente è come utilizzare un pannello Bootstrap per eseguire il rendering di un post con titolo, testo e tag. Nota che selectedPost
, tagObjects
e tag
sono tutte funzioni ausiliarie del modello blogPost. title
e text
sono campi del nostro documento.
<template name="blogPost">
{{#with selectedPost }}
<div class="blogPost panel panel-default">
<div class="panel-heading">
{{ title }}
</div>
{{ text }}
<div class="panel-footer">
<ul class="horizontal-tags">
{{#each tagObjects }}
<li class="tag removable_tag">
<div class="name">{{tag}}<i class="fa fa-times"></i></div>
</li>
{{/each}}
<li class="tag edittag">
<input type="text" id="edittag-input" value="" /><i class="fa fa-plus"></i>
</li>
</ul>
</div>
</div>
{{/with}}
</template>
Javascript
Successivamente, vogliamo configurare alcuni controller per restituire dati, implementare alcuni dati immessi e così via.
// you will need to set the selectedPostId session variable
// somewhere else in your application
Template.blogPost.selectedPost = function(){
return Posts.findOne({_id: Session.get('selectedPostId')});
}
// next, we use the _.map() function to read the array from our record
// and convert it into an array of objects that Handlebars/Spacebars can parse
Template.blogPost.tagObjects = function () {
var post_id = this._id;
return _.map(this.tags || [], function (tag) {
return {post_id: post_id, tag: tag};
});
};
// then we wire up click events
Template.blogPost.events({
'click .fa-plus': function (evt, tmpl) {
Posts.update(this._id, {$addToSet: {tags: value}});
},
'click .fa-times': function (evt) {
Posts.update({_id: this._id}, {$pull: {tags: this.tag}});
}
});
Messa in piega
Infine, vogliamo definire alcune viste diverse per telefono, tablet e desktop; e alcuni stili di interfaccia utente di base a seconda dell'input dell'utente. Questo esempio utilizza il precompilatore Less, sebbene la sintassi dovrebbe essere approssimativamente la stessa per Sass e Stylus.
// default desktop view
.fa-plus:hover{
cursor: pointer;
}
.fa-times:hover{
cursor: pointer;
}
// landscape orientation view for tablets
@media only screen and (min-width: 768px) {
.blogPost{
padding: 20px;
}
}
// portrait orientation view for tablets
@media only screen and (max-width: 768px) {
.blogPost{
padding: 0px;
border: 0px;
}
}
// phone view
@media only screen and (max-width: 480px) {
blogPost{
.panel-footer{
display: none;
}
}
}
Avvisi ed errori
Gli avvisi e gli errori sono quasi il più semplice di tutti i modelli di componenti Meteor. Sono così semplici, infatti, che a malapena si registrano come un modello in se stessi. Invece di aggiungere moduli o pattern FlashAlert, tutto quello che devi fare è disegnare un modello manubrio appropriato, aggiungere un helper e collegarlo a una variabile Session reattiva.
Prerequisiti
Il seguente codice richiede il precompilatore LESS e Bootstrap-3, rispettivamente. Avrai bisogno di eseguire i seguenti comandi al prompt dei comandi per farli funzionare.
meteor add less
meteor add ian:bootstrap-3
Modello oggetto documento: Definisci oggetto avviso Inizia aggiungendo alcuni elementi al modello dell'oggetto documento. In questo caso, vogliamo creare un elemento div per il nostro avviso, che è collegato a due helper del manubrio.
<template name="postsPage">
<div id="postsPage" class="page">
<div id="postsPageAlert" class="{{alertColor}}">{{alertMessage}}</div>
<div class="postsList">
<!-- other code you can ignore in this example -->
</div>
<div id="triggerAlertButton" class="btn btn-default">
</div>
</template>
Javascript: definizione degli helper dei modelli Quindi vogliamo collegare alcuni controller che popoleranno il modello di oggetto con i dati. Lo facciamo con due variabili di sessione reattive e due assistenti manubrio.
Session.setDefault('alertLevel', false);
Session.setDefault('alertMessage', "");
Template.postsPage.alertColor = function(){
if(Session.get('alertLevel') == "Success"){
return "alert alert-success";
}else if(Session.get('alertLevel') == "Info"){
return "alert alert-info";
}else if(Session.get('alertLevel') == "Warning"){
return "alert alert-warning";
}else if(Session.get('alertLevel') == "Danger"){
return "alert alert-danger";
}else{
return "alert alert-hidden"
}
}
Template.postsPage.alertMessage = function(){
return Session.get('alertMessage');
}
Styling: definizione della visibilità DOM Poi vogliamo tornare al nostro CSS e definire due viste dell'elemento postsPage. Nella prima vista, mostriamo tutti i contenuti nel nostro modello a oggetti. Nella seconda vista, vengono visualizzati solo alcuni dei contenuti del nostro modello a oggetti.
#postsPage{
.alert{
display: block;
}
.alert-hidden{
display: none;
}
}
Javascript: attivazione dell'avviso
Infine, torniamo ai nostri controllori e definiamo un controller di eventi, che attiva il nostro avviso quando viene fatto clic.
Template.postsPage.events({
'click #triggerAlertButton':function(){
Session.set('alertLevel', 'Success');
Session.set('alertMessage', 'You successfully read this important alert message.');
}
});
E questo è tutto ciò che c'è da fare! Super semplice, giusto? È ora possibile impostare le variabili di sessione alertLevel
e alertMessage
in qualsiasi punto della base di codice e l'applicazione visualizzerà in modo reattivo avvisi e messaggi di errore! :)
Flusso di lavoro a schede
Modello oggetto documento
Inizia creando le schede e i riquadri nel modello a oggetti ...
<template name="samplePage">
<div id="samplePage" class="page">
<ul class="nav nav-tabs">
<li id="firstPanelTab"><a href="#firstPanel">First</a></li>
<li id="secondPanelTab"><a href="#secondPanel">Second</a></li>
</ul>
<div id="firstPanel" class="{{firstPanelVisibility}}">
{{> firstPanel }}
</div>
<div id="secondPanel" class="{{secondPanelVisibility}}">
{{> secondPanel }}
</div>
</div>
</template>
Javascript
// this variable controls which tab is displayed and associated application state
Session.setDefault('selectedPanel', 1);
Template.name.helpers({
firstPanelVisibility: function (){
if(Session.get('selectedPanel') === 1){
return "visible";
}else{
return "hidden";
}
},
secondPanelVisibility: function (){
if(Session.get('selectedPanel') === 2){
return "visible";
}else{
return "hidden";
}
},
thirdPanelVisibility: function (){
if(Session.get('selectedPanel') === 3){
return "visible";
}else{
return "hidden";
}
},
firstPanelActive: function (){
if(Session.get('selectedPanel') === 1){
return "active panel-tab";
}else{
return "panel-tab";
}
},
secondPanelActive: function (){
if(Session.get('selectedPanel') === 2){
return "active panel-tab";
}else{
return "panel-tab";
}
},
thirdPanelActive: function (){
if(Session.get('selectedPanel') === 3){
return "active panel-tab";
}else{
return "panel-tab";
}
}
});
Messa in piega
.visible {
display: block;
visibility: visible;
}
.hidden {
display: none;
visibility: hidden;
}
Scheda attiva Per effetto aggiunto, è possibile estendere questo modello iniettando le classi per indicare la scheda attiva.
<li id="firstPanelTab" class="{{firstPanelActive}}"><a href="#firstPanel">First</a></li>
<li id="secondPanelTab" class="{{secondPanelActive}}"><a href="#secondPanel">Second</a></li>
Template.firstPanel.helpers({
firstPanelActive: function (){
if(Session.get('selectedPanel') === 1){
return "active";
}else{
return "";
}
},
secondPanelActive: function (){
if(Session.get('selectedPanel') === 2){
return "active";
}else{
return "";
}
},
});