Поиск…
замечания
Вышеупомянутые примеры Blaze очень совместимы с библиотекой http://bootsnipp.com/ , которая предоставляет только HTML и CSS для компонентов и оставляет javascript до разработчика. Это позволяет компонентам совместно использовать одни и те же методы сортировки, фильтрации, запроса и курсора.
Выпадающее меню
В следующем примере создается раскрывающееся меню Bootstrap, используя только Blaze и JQuery.
Объектная модель документа
<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
Очень общая задача - создать отзывчивые навигаторы и создать панели действий / нижнего колонтитула, которые имеют разные элементы управления на основе того, на какой странице находится пользователь, или на какую роль принадлежит пользователь. Давайте рассмотрим, как сделать эти элементы управления.
маршрутизатор
Router.configure({
layoutTemplate: 'appLayout',
});
Router.route('checklistPage', {
path: '/lists/:_id',
onBeforeAction: function() {
Session.set('selectedListId', this.params._id);
this.next();
},
yieldTemplates: {
'navbarFooter': {
to: 'footer'
}
}
});
Создание шаблона Navbar
<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>
Определение доходности в макете
<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>
модальности
Этот подход является методом чистого Blaze для переключения элементов пользовательского интерфейса в и из существования. Подумайте об этом как о замене модальных диалогов. На самом деле существует множество способов реализации модальных диалогов с использованием этого метода (просто добавьте фоновые маски и анимации).
Объектная модель документа
<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
Уровень базы данных Сначала мы хотим настроить протокол распространения данных, чтобы мы могли сохранять данные в базе данных и получать их клиенту. Необходимо создать три файла ... один на сервере, один на клиенте и один, который разделяют между ними.
// 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();
});
В этом примере предполагается следующая схема документа для шаблона тегов:
{
_id: "3xHCsDexdPHN6vt7P",
title: "Sample Title",
text: "Lorem ipsum, solar et...",
tags: ["foo", "bar", "zkrk", "squee"]
}
Объектная модель документа
Во-вторых, мы хотим создать нашу объектную модель в прикладном уровне. Ниже приведен пример использования панели Bootstrap для рендеринга сообщения с заголовком, текстом и тегами. Обратите внимание, что selectedPost
, tagObjects
и tag
являются вспомогательными функциями шаблона blogPost. title
и text
являются полями из нашей записи документа.
<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
Затем мы хотим настроить некоторые контроллеры для возврата данных, внедрения некоторых данных и т. Д.
// 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}});
}
});
стайлинг
Наконец, мы хотим определить несколько разных представлений для телефона, планшета и настольных компьютеров; и некоторый базовый стиль пользовательского интерфейса в зависимости от ввода пользователя. В этом примере используется прекомпилятор Less, хотя синтаксис должен быть примерно одинаковым для Sass и 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;
}
}
}
Оповещения и ошибки
Оповещения и ошибки - это самый простой из всех моделей компонентов Meteor. На самом деле они настолько просты, что они едва ли регистрируются как образец сами по себе. Вместо добавления модулей или шаблонов FlashAlert все, что вам действительно нужно сделать, это стиль подходящего шаблона руля, добавьте помощника и подключите его к реактивной переменной сеанса.
Предпосылки
Следующий код требует прекомпилятора LESS и Bootstrap-3 соответственно. Вам нужно будет запустить следующие команды в командной строке, чтобы заставить их работать.
meteor add less
meteor add ian:bootstrap-3
Объектная модель документа: определение объекта предупреждения Начните с добавления некоторых элементов в объектную модель документа. В этом случае мы хотим создать элемент div для нашего оповещения, который подключен до двух помощников Handlebar.
<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: определение помощников шаблонов. Затем мы хотим подключить некоторые контроллеры, которые будут заполнять объектную модель данными. Мы делаем это с двумя реактивными переменными сеанса и двумя помощниками руля.
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: определение видимости DOM. Затем мы хотим вернуться к нашему CSS и определить два представления элемента postsPage. В первом представлении мы отображаем все содержимое нашей объектной модели. Во втором представлении отображается только часть содержимого нашей объектной модели.
#postsPage{
.alert{
display: block;
}
.alert-hidden{
display: none;
}
}
Javascript: запуск оповещения
Наконец, мы возвращаемся к нашим контроллерам, и мы определяем контроллер событий, который вызывает наше предупреждение при нажатии.
Template.postsPage.events({
'click #triggerAlertButton':function(){
Session.set('alertLevel', 'Success');
Session.set('alertMessage', 'You successfully read this important alert message.');
}
});
И это все! Супер простой, не так ли? Теперь вы можете установить переменные сеанса alertLevel
и alertMessage
любом месте вашей кодовой базы, и ваше приложение будет реагировать на предупреждения и сообщения об ошибках! :)
Рабочий процесс с вкладками
Объектная модель документа
Начните с создания вкладок и панелей в объектной модели ...
<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";
}
}
});
стайлинг
.visible {
display: block;
visibility: visible;
}
.hidden {
display: none;
visibility: hidden;
}
Активная вкладка. Для дополнительного эффекта вы можете расширить этот шаблон, введя классы, чтобы указать активную вкладку.
<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 "";
}
},
});