Szukaj…


Uwagi

Powyższe przykłady Blaze są wysoce kompatybilne z biblioteką http://bootsnipp.com/ , która zapewnia tylko HTML i CSS dla komponentów, a javascript pozostaje w gestii programisty. Pozwala to komponentom na dzielenie tych samych podstawowych metod sortowania, filtrowania, zapytań i kursorów.

Poniższy przykład tworzy menu rozwijane Bootstrap, używając tylko Blaze i bez JQuery.

Dokumentowy model obiektowy


    <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);
  },
});

Paski nawigacyjne

Bardzo częstym zadaniem jest tworzenie responsywnych pasków nawigacyjnych i tworzenie pasków akcji / stopki, które mają różne elementy sterujące w zależności od strony, na której użytkownik się znajduje lub do jakiej roli należy użytkownik. Zobaczmy, jak wykonać te kontrole.

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'
      }
    }
  });

Utwórz szablon paska nawigacyjnego

<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>

Zdefiniuj plony w układzie

<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>

Moduły

To śledzenie jest czystym podejściem do włączania i wyłączania elementów interfejsu użytkownika. Pomyśl o tym jako o zamienniku modalnych okien dialogowych. W rzeczywistości istnieje wiele sposobów implementacji modalnych okien dialogowych za pomocą tej metody (wystarczy dodać maski tła i animacje).

Dokumentowy model obiektowy

<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;
  }
}

Tagowanie

Warstwa bazy danych Po pierwsze, chcemy skonfigurować protokół dystrybucji danych, aby upewnić się, że możemy zachować dane w bazie danych i przekazać je klientowi. Trzeba utworzyć trzy pliki ... jeden na serwerze, jeden na kliencie i jeden wspólny między nimi.

// 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();
});

W tym przykładzie przyjęto następujący schemat dokumentu dla wzorca znakowania:

{
  _id: "3xHCsDexdPHN6vt7P",
  title: "Sample Title",
  text: "Lorem ipsum, solar et...",
  tags: ["foo", "bar", "zkrk", "squee"]
}

Dokumentowy model obiektowy
Po drugie, chcemy stworzyć nasz model obiektowy w warstwie aplikacji. Poniżej przedstawiono sposób użycia panelu Bootstrap do renderowania postu z tytułem, tekstem i tagami. Pamiętaj, że selectedPost , tagObjects i tag są funkcjami pomocniczymi szablonu blogPost. title i text to pola z naszego rekordu dokumentu.

<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
Następnie chcemy skonfigurować niektóre kontrolery do zwracania danych, zaimplementować wprowadzanie danych i tak dalej.

// 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}});
    }
});

Stylizacja
Na koniec chcemy zdefiniować różne widoki dla telefonu, tabletu i komputera stacjonarnego; i niektóre podstawowe style interfejsu użytkownika w zależności od danych wejściowych użytkownika. W tym przykładzie użyto prekompilatora Less, chociaż składnia powinna być mniej więcej taka sama dla Sassa i Stylusa.

// 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;
    }
  }
}

Alerty i błędy

Alerty i błędy są prawie najprostszym ze wszystkich wzorców komponentów Meteora. Są tak proste, że ledwo rejestrują się jako wzór. Zamiast dodawać moduły lub wzorce FlashAlert, wszystko, co naprawdę musisz zrobić, to stylizować odpowiedni szablon kierownicy, dodać pomocnika i połączyć go z reaktywną zmienną sesji.

Wymagania wstępne
Poniższy kod wymaga odpowiednio prekompilatora LESS i Bootstrap-3. Aby uruchomić je, musisz uruchomić następujące polecenia w wierszu polecenia.

meteor add less
meteor add ian:bootstrap-3 

Model obiektu dokumentu: Zdefiniuj obiekt alertu Zacznij od dodania niektórych elementów do modelu obiektu dokumentu. W tym przypadku chcemy utworzyć element div dla naszego alertu, który będzie połączony z maksymalnie dwoma pomocnikami Kierownicy.

<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: Definiowanie pomocników szablonów Następnie chcemy połączyć niektóre kontrolery, które zapełnią model obiektu danymi. Robimy to za pomocą dwóch reaktywnych zmiennych sesji i dwóch pomocników kierownicy.

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');
}

Stylizacja: Zdefiniuj widoczność DOM Następnie chcemy wrócić do naszego CSS i zdefiniować dwa widoki elementu postsPage. W pierwszym Widoku wyświetlamy całą zawartość naszego modelu obiektowego. W drugim widoku wyświetlana jest tylko część zawartości naszego modelu obiektowego.

#postsPage{
  .alert{
    display: block;
  }
  .alert-hidden{
    display: none;
  }
}

JavaScript: wyzwalanie alertu
Na koniec wracamy do naszych kontrolerów i definiujemy kontroler zdarzeń, który wyzwoli nasz alert po kliknięciu.

Template.postsPage.events({
  'click #triggerAlertButton':function(){
    Session.set('alertLevel', 'Success');
    Session.set('alertMessage', 'You successfully read this important alert message.');
  }
});

I to wszystko! Super proste, prawda? Możesz teraz ustawić zmienne sesji alertLevel i alertMessage w dowolnym miejscu w bazie kodu, a Twoja aplikacja będzie reaktywnie wyświetlać alerty i komunikaty o błędach! :)

Przepływ pracy w kartach

Dokumentowy model obiektowy
Zacznij od utworzenia zakładek i paneli w modelu obiektowym ...

<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";
    }
  }
});

Stylizacja

.visible {
  display: block;
  visibility: visible;
}
.hidden {
  display: none;
  visibility: hidden;
}

Aktywna karta Aby uzyskać dodatkowy efekt, możesz rozszerzyć ten wzór, wstrzykując klasy wskazujące aktywną kartę.

<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 "";
    }
  },
});



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow