13/04/2018 Development / angular

Quem trabalha com firebase, deve "OBRIGATORIAMENTE" seguir oque os caras falam:

Melhorar a eficiência dos listeners

Coloque os listeners na última parte possível do caminho para limitar a quantidade de dados que eles sincronizam. Seus listeners devem estar perto dos dados que você quer detectar. Não coloque listeners na raiz do banco de dados, pois isso resulta em downloads de todo o seu banco de dados.

Adicione consultas para limitar os dados retornados pelas suas operações de detecção e use listeners que fazem o download somente de atualizações de dados. Por exemplo, on() em vez de once(). Use .once() somente em ações que realmente não exigem atualizações de dados. Além disso, classifique suas consultas com orderByKey() sempre que possível para alcançar o melhor desempenho. A classificação com orderByChild() pode ser de seis a oito vezes mais lenta. A classificação com orderByValue(), por sua vez, pode ser muito lenta para grandes conjuntos de dados porque requer uma leitura de todo o local, desde a camada de persistência.

Lembre-se também de adicionar listeners de maneira dinâmica e de removê-los quando não forem mais necessários.

#ficadica

13/03/2018 Development / angular

Oque é um decorator?

Basicamente ele é utilizado para sobreescrever métodos antes que de fato o método original seja chamado!

Vamos imaginar o seguinte cenario:

Temos alguns endpoints que realizam Create e Update no banco. E para cada um desses métodos, eu quero salvar o dia da criacao do registro e quem fez o cadastro, e o dia da alteracao do registro e que fez o cadastro!

Usando MongoDB é muito facil fazer isso, basta a gente indicar no model um timestamp: true

Exemplo:

var clienteSchema = new mongoose.Schema({

nome: {type: String}

},{

    timestamps: true

});

Qualquer inclusão ou alteração que ocorrer, o mongo já incluirá os valores da data da criação e ou alteração!

Mas no nosso caso, não estamos usando MONGO e tambem queremos incluir a pessoa que fez a ação!

Voltando ao nosso cenário, criamos o nosso Service que receberá os dados e enviará para API.

Eu vou fazer bem básico, porque a intenção aqui é focar no decorator!!!

Service.create = (data)=> {

    data.createdAt = firebase.database.ServerValue.TIMESTAMP; // ou new Date().getTime()

    data.createdBy = firebase.auth().currentUser.displayName; // ou currentUser.uid;

  return this._$firebaseArray(firebase.database.ref('suaRefencia')).$add(data)  

}

 

Service.update = (id, data)=> {

    data.createdAt = firebase.database.ServerValue.TIMESTAMP; // ou new Date().getTime()

    data.createdBy = firebase.auth().currentUser.displayName; // ou currentUser.uid;

  return this._$firebaseObject(firebase.database.ref('suaRefencia').child(id)).$save(data)  

}

Olha que chato, se toda vez que a gente criar um servico, ter que ficar colocando esse código, createdAt, createdBy, updatedAt, updatedBy

O ideial é quando a gente chamar o $add ou $save, antes de executar o método, ele inclua essas propriedades no nsso objeto data.

É ai que entra o decorator!!!

let app = angular.module('app', []);

app.config(function($provide) {

    $provide.decorator('$firebaseArray', function($delegate, $window) {

        var _add = $delegate.prototype.$add;

        $delegate.prototype.$add = function (newData) {

            newData['createdAt'] = $window.firebase.database.ServerValue.TIMESTAMP;

            newData['createdBy'] = $window.firebase.auth().currentUser.displayName; //uid

 

            return _add.call(this, newData);

        };

        return $delegate;

    });

})

app.config(function($provide) {

    $provide.decorator('$firebaseObject', function($delegate, $window) {

        var _save = $delegate.prototype.$save;

        $delegate.prototype.$save = function () {

            this['updatedAt'] = $window.firebase.database.ServerValue.TIMESTAMP;

            this['updatedBy'] = $window.firebase.auth().currentUser.displayName;

            return _save.call(this);

        };

        return $delegate;

    });

})

Agora no nosso controller, a gente faz a chamada do Service

let data = {

  nome: 'Joao da Silva';

  idade: 33

}

Service.create(data);

Nosso service chamado o firebaseArray, mas antes entra no decorator, que insere a data da criacao e o nome do usuário logado no firebase!

E assim, a gente finaliza nossa tarefa.

Espero que ajude!

 

 

 

 

 

 

 

 

23/11/2017 Development / angular

No projeto da Odete, eu estava implementando um esquema para abrir o modal quando o usuário clicasse no cadeado.

Esse cadeado fica dentro de um componente chamado perfil. E aqui eu posto a minha solução.

Na minha classe perfil, eu coloquei mais um component

@Component({

selector: 'app-modal-content',

moduleId: module.id,

templateUrl: './perfil.cadastroConfiavel.modal.html'

})

export class ModalContentComponent {

constructor(public bsModalRef: BsModalRef) {}

}

dentro da minha classe perfil, fiz o metodo que chama o modal

export class PerfilComponent implements OnInit {

 

@Input('model') model;

public modalRef: BsModalRef;

 

constructor(private service: ColaboradorService, private modalService: BsModalService) { }

openModal() {

this.modalRef = this.modalService.show(ModalContentComponent);

}

Aqui esta o pulo do gato. No app.module.ts tem que importar

import { PerfilComponent, ModalContentComponent } from './perfil/perfil.component';

e no ngModule

@NgModule({

declarations: [

PerfilComponent,

ModalContentComponent

],

entryComponents: [ ModalContentComponent ],

Thats Great!

23/11/2017 Development / angular

In angular1 we use 

$locationProvider.html5Mode({
  enabled: true,
  requireBase: false
});
<head>
  <base href="/">
  ...
</head>

In angular 5

import in -> app.module.ts

import {APP_BASE_HREF} from '@angular/common';

and include in yours providers

providers: [{provide: APP_BASE_HREF, useValue: '/'}]

thats great!

22/11/2017 Development / angular

@Injectable()

export class ColaboradorService {

constructor(private http: Http) { }

getColaboradores(filters): Observable<any[]> {

return this.http.get('https://odete-app.herokuapp.com/colaboradores', filters)

.map(response => response.json())

.map((messages: Object[]) => {

return messages.map(message => message);

});

}

}

My component

import { ColaboradorService } from '../colaborador.service';

export class MainComponent implements OnInit {

data: Array<any> = [];

constructor(private service: ColaboradorService) {}

}

ngOnInit() {

this.service.getColaboradores(this.filters).subscribe(colaborades => this.data = colaborades);

}

Easy!

 

20/11/2017 Development / angular

export class AboutComponent implements OnInit {

 

asks = [];

 

constructor() {

 

this.asks = [{

ask : 'O cadastro é gratuito?',

ans : 'Sim. Completamente grátis.'

},

{

ask : 'Preciso fazer um cadastro?',

ans : 'Se você quiser participar do nosso banco de dados ficamos felizes em compartilhar o seu interesse em oferecer seus serviços ou contratar profissionais da área.'

},

{

ask : 'Quero oferecer meus serviços, oque devo fazer?',

ans : 'Acesse nosso formulário de cadastro e preencha com seus dados pessoais, escolha uma foto de perfil e no final selecione os serviços que você realiza.'

},

{

ask : 'Como funciona a aprovação do cadastro?',

ans : 'Nossa equipe entrará em contato para conferir seu cadastro e habilitar seu registro.'

},

{

ask : 'Quanto posso cobrar pelos meus serviços?',

ans : 'Você pode cobrar quanto você achar justo pelos seus serviços, nós indicamos colocar um valor pela diária ou por hora trabalhada.'

},

{

ask : 'Como vou receber pelos meus serviços?',

ans : 'A negociação em geral, como execução do serviço, data e hora agendada e a forma de pagamento é de responsalidade do contratante e da contratada.'

},

{

ask : 'Como posso avaliar um serviço executado?',

ans : 'Estamos em constante desenvolvimento e aprimoramento de nossas funcionalidades, essa funcionalidade estará disponível em breve.'

},

{

ask : 'Como posso avaliar um bagunceiro?',

ans : 'Estamos em constante desenvolvimento e aprimoramento de nossas funcionalidades, essa funcionalidade estará disponível em breve.'

}

];

}

 

<accordion>

<accordion-group heading="{{q.ask}}" class="mb-2" *ngFor="let q of asks; let i = index" [isOpen]="i === 0">

{{q.ans}}

</accordion-group>

</accordion>

20/11/2017 Development / angular

There are different type :

type one

[class.my-class]="step=='step1'"

type two

[ngClass]="{'my-class': step=='step1'}"

type three

[ngClass]="{1:'my-class1',2:'my-class2',3:'my-class4'}[step]"

type four

[ngClass]="(step=='step1')?'my-class1':'my-class2'"
20/11/2017 Development / angular
<!-- Angular -->
<ul>
  <li *ngFor="let item of items; let i = index">
    {{i}} {{item}}
  </li>
</ul>
<ul>
  <li *ngFor=" let item of items; trackBy: trackByFn;">
    {{item}}
  </li>
</ul>
// Method in component class
trackByFn(index, item) {
  return item.id;
}
18/12/2016 Development / angular

Quando criamos um controller usando angular é normal usarmos 

$scope.varivel = 'Xibata';

e na view usarmos {{variavel}}

ou

$scope.obj = {};
$scope.obj.variavel = 'Xibatinha';

e na view {{obj.variavel}}

E tambem existe a seguinte situacao, quando a gente quer usar o $rootScope para usar de forma global de maneira mais rapida, o certo é usar Service ou Factory ou alguma outra coisa, mas isso aqui que eu quero falar é um pulinho do gato rapido.

Pois bem, quando usamos $rootScope e queremos print o objeto na view, usamos:

$rootScope.variavel = 'Xibaaaaata';

{{$root.variavel}}

Espero que sirva!

 

17/12/2016 Development / angular

md-select readonly="true" or readonly="readonly" not run :-( 

use  ng-attr-disabled="true" :-)

Espero que sirva!

17/12/2016 Development / angular

Include in css

md-dialog.fullscreen-dialog {
    max-width: 100%;
    max-height: 100%;
    width: 100%;
    height: 100%;
    border-radius: 0;
}

In html

<md-dialog aria-label="Dialog" class="fullscreen-dialog">

Espero que sirva!

23/11/2016 Development / angular

2 tipos de inicializar o projeto com angular

    // pure angular
    (function() {
        var initInjector = angular.injector(['ng', 'requestFromAPIService', 'config', 'ngCookies']);
        var $http = initInjector.get('$http');
        var requestFromAPI = initInjector.get('requestFromAPI');
        var ENV = initInjector.get('ENV');
        var $cookies = initInjector.get('$cookies');

        if (!ENV.disable_auth) {

            if ($cookies.get('wrsso') === '' || !$cookies.get('wrsso')) {
                console.log('initialize redirecionando para o auth');
                window.location.href = '/auth/webradar';
                return false;
            }

            requestFromAPI.request(ENV.rocketAppUrl + 'capabilities', '', {}, 'clearance').then(function(resp){

                if(!resp || !resp.data || !resp.data.roles || resp.data.roles.length === 0){
                    console.log('falha na resposta do initialize rule - redirecionando para o auth');
                    window.location.href = '/auth/webradar';
                    return false;                
                }

                angular.module('APP_CONFIG', []).constant('APP_CONFIG', resp.data);
                angular.element(document).ready(function() {
                    angular.bootstrap(document, ['rocketUI']);
                });
            }, function(err){
                window.location.href = '/auth/webradar';
            });
        }else{
            angular.module('APP_CONFIG', []).constant('APP_CONFIG', {roles: ['manager']});
            angular.element(document).ready(function() {
                angular.bootstrap(document, ['rocketUI']);
            });            
        }

    })();

    // deferredBootstrapper-lib
    // deferredBootstrapper.bootstrap({
    //   element: document.body,
    //   module: 'rocketUI',
    //   injectorModules: ['requestFromAPIService', 'config'],
    //   resolve: {
    //     APP_CONFIG: ['requestFromAPI', 'ENV', function (requestFromAPI, ENV) {        
    //         return requestFromAPI.request(ENV.rocketAppUrl + 'capabilities', '', {}, 'clearance');
    //     }]
    //   }
    // });

25/01/2016 Development / angular

This a simple example of queues using setIterval. This is a best practices for iterator object array.

var myApp = angular.module('myApp',[]);

function MyCtrl($scope) {
    
    $scope.queue = [];
    
    $scope.addQueue = function(){
       
        $scope.queue.push({
          name : $scope.name,
        money:$scope.money
      });
    }
    
    
    $scope.tratarFila = function(){

            if($scope.queue.length === 0){
          return false;
      }

            var indice = $scope.queue.filter(function(item){
          return item.money > 0;
        }); 
      
      if(indice.length === 0){
          return false;
      }

            var index = Math.floor(Math.random() * indice.length);
            var fila = indice[index];

            if(fila.money > 0){
          fila.money--;
        $scope.$apply();
      }
    };
    
    setInterval(function(){
        $scope.tratarFila();
    }, 50);
    
}

 

<div ng-controller="MyCtrl">
  
  <input ng-model="name" placeholder="nome"/>
  <input ng-model="money" placeholder="money"/>
  <button ng-click="addQueue()">
  adicionar user
  </button>
  <hr/>
  <ul>
  <li ng-repeat="q in queue">{{q.name}} - {{q.money}}</li>
  </ul>
  </ul>
  
</div>

http://jsfiddle.net/HB7LU/22825/

 

16/06/2015 Development / angular

I development a new CMS usign angular and this CMS has a menu recursive.

My solution:

angular.module("myApp", []).
controller("TreeController", ['$scope', function($scope) {
    $scope.delete = function(data) {
        data.nodes = [];
    };
    $scope.add = function(data) {
        var post = data.nodes.length + 1;
        var newName = data.name + '-' + post;
        data.nodes.push({name: newName,nodes: []});

 

<script type="text/ng-template"  id="tree_item_renderer.html">
    {{data.name}}
    <button ng-click="add(data)">Add node</button>
    <button ng-click="delete(data)" ng-show="data.nodes.length > 0">Delete nodes</button>
    <ul>
        <li ng-repeat="data in data.nodes" ng-include="'tree_item_renderer.html'"></li>
    </ul>
</script>

<ul ng-app="Application" ng-controller="TreeController">
    <li ng-repeat="data in tree" ng-include="'tree_item_renderer.html'"></li>
</ul>

http://jsfiddle.net/brendanowen/uXbn6/8/

18/06/2015 Development / angular

In Angular Material Design, exists any importants classes CSS.

  • md-primary
  • md-war
  • md-accent

This is classes, indicator the first colors on elements.

md-default-theme // Indicator the theme default

md-button // Indicator the button

md-raised // This is used for display: block in element em apply background color.

md-cornered // Create a button com border-radius: 0

md-padding // Add padding 16px default

Attibute layout-padding // Add padding 8px default

layout-wrap

 flex-sm="100" flex-gt-sm="50" flex-gt-md="25" // resolution

.md-ripple-container // add position absolute, left:0 top:0 width: 100%, height: 100%, pointer-events

md-fab md-fab-bottom-left fab-position // insert button with border-radius 50% left or right , bottom or top

md-medium-tall // used in <md-toolbar> 

02/06/2015 Development / angular

I did update the website wallstreetvideo.com.br

I used angularjs with materializecss because i want the material-design of  apperance.

I am studying angularjs, material-design and also frameworks.

My tips:

fastclick - change the click for touchstart

desable selection
-webkit-tap-highlight-color: rgba(0,0,0);
user-select:none

best scroll
-webkit-overflow-scrolling:touch;

acelerate application
-wekbit-transform: translate3d(0,0,0);

body no move
document.ontouchstart = function(){
event.prevendDefualt();
}

bbUI.js - framework of UI to mobile;

Frameworks

Finallity the website of my client - wallstreetvideo - I used only angular material design, never other framework.

06/10/2014 Development / angular

Quando usamos html5 mode do angular, precisamos reconfigurar as rotas dentro do servidor.

Segue um web.config de exemplo.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
    <rewrite>
      <!--This directive was not converted because it is not supported by IIS: RewriteBase /.-->
      <rules>
        <rule name="Imported Rule 1" stopProcessing="true">
          <match url="^index\.html" ignoreCase="false" />
          <action type="None" />
        </rule>
        <rule name="Imported Rule 2" stopProcessing="true">
          <match url="." ignoreCase="false" />
          <conditions>
            <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
          </conditions>
          <action type="Rewrite" url="/index.html" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
  </configuration>

Espero que sirva!