"Pensando no AngularJS" se eu tiver um histórico de jQuery? [fechadas]

4514

Suponha que eu esteja familiarizado com o desenvolvimento de aplicativos do lado do cliente no jQuery , mas agora gostaria de começar a usar o AngularJS . Você pode descrever a mudança de paradigma necessária? Aqui estão algumas perguntas que podem ajudá-lo a estruturar uma resposta:

  • Como faço para arquitetar e projetar aplicativos da Web do lado do cliente de maneira diferente? Qual é a maior diferença?
  • O que devo parar de fazer / usar; O que devo começar a fazer / usar?
  • Existem considerações / restrições do lado do servidor?

Não estou procurando uma comparação detalhada entre jQuerye AngularJS.

Mark Rajcok
fonte
Para aqueles familiarizados com "ASP.NET MVC" ou "RoR" - basta pensar em Angular como "MVC do lado do cliente" e é isso.
Serge Shultz 27/05

Respostas:

7178

1. Não crie sua página e altere-a com manipulações DOM

No jQuery, você cria uma página e a torna dinâmica. Isso ocorre porque o jQuery foi projetado para aumentar e cresceu incrivelmente a partir dessa premissa simples.

Mas no AngularJS, você deve começar do zero com sua arquitetura em mente. Em vez de começar pensando "Eu tenho essa parte do DOM e quero fazer com que ela faça X", você precisa começar com o que deseja realizar, depois desenvolver o aplicativo e, finalmente, projetar sua visualização.

2. Não aumente o jQuery com o AngularJS

Da mesma forma, não comece com a idéia de que o jQuery executa X, Y e Z; portanto, adicionarei o AngularJS sobre isso para modelos e controladores. Isso é realmente tentador quando você está começando, e é por isso que eu sempre recomendo que os novos desenvolvedores do AngularJS não usem jQuery, pelo menos até que se acostumem a fazer as coisas da "maneira angular".

Eu já vi muitos desenvolvedores aqui e na lista de discussão criarem essas soluções elaboradas com plugins jQuery de 150 ou 200 linhas de código que eles colam no AngularJS com uma coleção de retornos de chamada $applyes que são confusos e complicados; mas eles acabam conseguindo funcionar! O problema é que, na maioria dos casos, o plugin jQuery pode ser reescrito no AngularJS em uma fração do código, onde, de repente, tudo se torna compreensível e direto.

O ponto principal é o seguinte: ao solucionar, primeiro "pense no AngularJS"; se você não consegue pensar em uma solução, pergunte à comunidade; Se depois de tudo isso não existe solução fácil, então fique à vontade para alcançar o jQuery. Mas não deixe o jQuery se tornar uma muleta ou você nunca dominará o AngularJS.

3. Pense sempre em termos de arquitetura

Primeiro, saiba que aplicativos de página única são aplicativos . Eles não são páginas da web. Portanto, precisamos pensar como um desenvolvedor do lado do servidor, além de pensar como um desenvolvedor do lado do cliente. Temos que pensar em como dividir nosso aplicativo em componentes individuais, extensíveis e testáveis.

Então, como você faz isso? Como você "pensa no AngularJS"? Aqui estão alguns princípios gerais, contrastados com o jQuery.

A vista é o "registro oficial"

No jQuery, alteramos programaticamente a exibição. Poderíamos ter um menu suspenso definido da seguinte ulforma:

<ul class="main-menu">
    <li class="active">
        <a href="#/home">Home</a>
    </li>
    <li>
        <a href="#/menu1">Menu 1</a>
        <ul>
            <li><a href="#/sm1">Submenu 1</a></li>
            <li><a href="#/sm2">Submenu 2</a></li>
            <li><a href="#/sm3">Submenu 3</a></li>
        </ul>
    </li>
    <li>
        <a href="#/home">Menu 2</a>
    </li>
</ul>

No jQuery, em nossa lógica de aplicação, nós o ativávamos com algo como:

$('.main-menu').dropdownMenu();

Quando apenas olhamos para a vista, não é imediatamente óbvio que existe alguma funcionalidade aqui. Para pequenas aplicações, tudo bem. Mas para aplicativos não triviais, as coisas rapidamente ficam confusas e difíceis de manter.

No AngularJS, no entanto, a visualização é o registro oficial da funcionalidade baseada em visualização. Nossa uldeclaração ficaria assim:

<ul class="main-menu" dropdown-menu>
    ...
</ul>

Esses dois fazem a mesma coisa, mas na versão AngularJS, qualquer um que olhe o modelo sabe o que deve acontecer. Sempre que um novo membro da equipe de desenvolvimento entra em cena, ela pode olhar para isso e depois saber que existe uma diretiva chamada dropdownMenuoperando nela; ela não precisa intuir a resposta certa ou filtrar qualquer código. A visão nos dizia o que deveria acontecer. Muito mais limpo.

Os desenvolvedores iniciantes no AngularJS costumam fazer uma pergunta como: como encontro todos os links de um tipo específico e adiciono uma diretiva a eles. O desenvolvedor sempre fica surpreso quando respondemos: você não. Mas a razão de você não fazer isso é que isso é como meio jQuery, meio AngularJS e não é bom. O problema aqui é que o desenvolvedor está tentando "executar jQuery" no contexto do AngularJS. Isso nunca vai funcionar bem. A vista é o registro oficial. Fora de uma diretiva (mais sobre isso abaixo), você nunca muda nunca o DOM. E as diretivas são aplicadas na exibição , para que a intenção seja clara.

Lembre-se: não projete e marque. Você deve arquitetar e projetar.

Ligação de dados

Esse é, de longe, um dos recursos mais impressionantes do AngularJS e elimina grande parte da necessidade de fazer os tipos de manipulações DOM mencionadas na seção anterior. O AngularJS atualizará automaticamente sua visualização para que você não precise! No jQuery, respondemos a eventos e, em seguida, atualizamos o conteúdo. Algo como:

$.ajax({
  url: '/myEndpoint.json',
  success: function ( data, status ) {
    $('ul#log').append('<li>Data Received!</li>');
  }
});

Para uma visão parecida com esta:

<ul class="messages" id="log">
</ul>

Além de misturar preocupações, também temos os mesmos problemas de intenção de intenção que mencionei antes. Mais importante, porém, tivemos que fazer referência e atualizar manualmente um nó DOM. E se quisermos excluir uma entrada de log, também precisamos codificar o DOM para isso. Como testamos a lógica além do DOM? E se quisermos mudar a apresentação?

Isso é um pouco bagunçado e um pouco frágil. Mas no AngularJS, podemos fazer isso:

$http( '/myEndpoint.json' ).then( function ( response ) {
    $scope.log.push( { msg: 'Data Received!' } );
});

E nossa visão pode ser assim:

<ul class="messages">
    <li ng-repeat="entry in log">{{ entry.msg }}</li>
</ul>

Mas, nesse caso, nossa visão poderia ser assim:

<div class="messages">
    <div class="alert" ng-repeat="entry in log">
        {{ entry.msg }}
    </div>
</div>

E agora, em vez de usar uma lista não ordenada, estamos usando caixas de alerta do Bootstrap. E nunca tivemos que alterar o código do controlador! Mais importante, porém, não importa onde ou como o log é atualizado, a exibição também será alterada. Automaticamente. Arrumado!

Embora eu não tenha mostrado aqui, a ligação de dados é bidirecional. Então, essas mensagens de log também pode ser editável no modo de exibição apenas fazendo isso: <input ng-model="entry.msg" />. E houve muita alegria.

Camada de modelo distinta

No jQuery, o DOM é como o modelo. Mas no AngularJS, temos uma camada de modelo separada que podemos gerenciar da maneira que quisermos, completamente independente da visualização. Isso ajuda na ligação de dados acima, mantém a separação de preocupações e introduz uma testabilidade muito maior. Outras respostas mencionaram esse ponto, então vou deixar por isso mesmo.

Separação de preocupações

E todos os itens acima se vinculam a esse tema abrangente: mantenha suas preocupações separadas. Sua visão atua como o registro oficial do que deveria acontecer (na maior parte); seu modelo representa seus dados; você tem uma camada de serviço para executar tarefas reutilizáveis; você manipula o DOM e aumenta sua visão com diretivas; e você cola tudo junto com os controladores. Isso também foi mencionado em outras respostas, e a única coisa que gostaria de acrescentar diz respeito à testabilidade, que discuto em outra seção abaixo.

Injeção de dependência

Para nos ajudar com a separação de preocupações é a injeção de dependência (DI). Se você vem de uma linguagem do lado do servidor (de Java para PHP ), provavelmente já conhece esse conceito, mas se você é do lado do cliente e vem do jQuery, esse conceito pode parecer algo bobo, supérfluo e moderno . Mas isso não. :-)

De uma perspectiva ampla, DI significa que você pode declarar componentes muito livremente e, a partir de qualquer outro componente, basta solicitar uma instância e ela será concedida. Você não precisa saber sobre a ordem de carregamento, nem os locais dos arquivos, nem nada do tipo. A energia pode não estar imediatamente visível, mas fornecerei apenas um exemplo (comum): teste.

Digamos que em nosso aplicativo, exigimos um serviço que implemente o armazenamento do servidor por meio de uma API REST e, dependendo do estado do aplicativo, também do armazenamento local. Ao executar testes em nossos controladores, não queremos ter que nos comunicar com o servidor - afinal, estamos testando o controlador . Podemos apenas adicionar um serviço simulado com o mesmo nome que o nosso componente original, e o injetor garantirá que nosso controlador obtenha o falso automaticamente - nosso controlador não sabe e não precisa saber a diferença.

Falando em testes ...

4. Desenvolvimento orientado a testes - sempre

Isso é realmente parte da seção 3 sobre arquitetura, mas é tão importante que eu estou colocando como sua própria seção de nível superior.

De todos os muitos plugins jQuery que você viu, usou ou escreveu, quantos deles tinham um conjunto de testes que o acompanha? Não são muitos, porque o jQuery não é muito receptivo a isso. Mas AngularJS é.

No jQuery, a única maneira de testar é geralmente criar o componente independentemente, com uma página de amostra / demonstração, na qual nossos testes podem executar a manipulação do DOM. Então nós temos que desenvolver um componente separadamente e , em seguida, integrá-lo em nossa aplicação. Que inconveniente! Na maioria das vezes, ao desenvolver com o jQuery, optamos pelo desenvolvimento iterativo, em vez do orientado a testes. E quem poderia nos culpar?

Mas, como temos uma separação de preocupações, podemos fazer o desenvolvimento orientado a testes iterativamente no AngularJS! Por exemplo, digamos que queremos uma diretiva super simples para indicar em nosso menu qual é a nossa rota atual. Podemos declarar o que queremos na visualização de nosso aplicativo:

<a href="/hello" when-active>Hello</a>

Ok, agora podemos escrever um teste para a when-activediretiva inexistente :

it( 'should add "active" when the route changes', inject(function() {
    var elm = $compile( '<a href="https://stackoverflow.com/hello" when-active>Hello</a>' )( $scope );

    $location.path('/not-matching');
    expect( elm.hasClass('active') ).toBeFalsey();

    $location.path( '/hello' );
    expect( elm.hasClass('active') ).toBeTruthy();
}));

E quando executamos nosso teste, podemos confirmar que ele falha. Somente agora devemos criar nossa diretiva:

.directive( 'whenActive', function ( $location ) {
    return {
        scope: true,
        link: function ( scope, element, attrs ) {
            scope.$on( '$routeChangeSuccess', function () {
                if ( $location.path() == element.attr( 'href' ) ) {
                    element.addClass( 'active' );
                }
                else {
                    element.removeClass( 'active' );
                }
            });
        }
    };
});

Nosso teste agora passa e nosso menu é executado conforme solicitado. Nosso desenvolvimento é tanto iterativo e orientado a testes. Mal-legal.

5. Conceitualmente, as diretivas não são jQuery empacotadas

Você geralmente ouvirá "apenas manipula DOM em uma diretiva". Isso é uma necessidade. Trate-o com a devida deferência!

Mas vamos mergulhar um pouco mais fundo ...

Algumas diretivas simplesmente decoram o que já está na visão (pense ngClass) e, portanto, às vezes fazem a manipulação do DOM imediatamente e, basicamente, são feitas. Mas se uma diretiva é como um "widget" e tem um modelo, ela também deve respeitar a separação de preocupações. Ou seja, o modelo também deve permanecer amplamente independente de sua implementação nas funções de link e controlador.

O AngularJS vem com um conjunto inteiro de ferramentas para tornar isso muito fácil; com ngClasspodemos atualizar dinamicamente a classe; ngModelpermite ligação de dados bidirecional; ngShowe ngHidemostrar ou ocultar programaticamente um elemento; e muito mais - incluindo os que escrevemos. Em outras palavras, podemos fazer todos os tipos de grandiosidade sem manipulação do DOM. Quanto menos manipulação do DOM, mais fáceis são as diretivas de teste, mais fáceis de modelar, mais fáceis de mudar no futuro e mais reutilizáveis ​​e distribuíveis.

Eu vejo muitos desenvolvedores novos no AngularJS usando diretivas como o local para lançar um monte de jQuery. Em outras palavras, eles pensam "como não posso manipular DOM no controlador, levarei esse código para uma diretiva". Embora isso certamente seja muito melhor, muitas vezes ainda está errado .

Pense no logger que programamos na seção 3. Mesmo se colocarmos isso em uma diretiva, ainda queremos fazê-lo da "maneira angular". Ele ainda não tem qualquer manipulação DOM! Há muitas vezes em que a manipulação do DOM é necessária, mas é muito mais raro do que você pensa! Antes de fazer a manipulação do DOM em qualquer lugar do seu aplicativo, pergunte-se se você realmente precisa. Pode haver uma maneira melhor.

Aqui está um exemplo rápido que mostra o padrão que eu vejo com mais frequência. Queremos um botão de alternância. (Nota: este exemplo é um pouco artificial e muito detalhado para representar casos mais complicados que são resolvidos exatamente da mesma maneira.)

.directive( 'myDirective', function () {
    return {
        template: '<a class="btn">Toggle me!</a>',
        link: function ( scope, element, attrs ) {
            var on = false;

            $(element).click( function () {
                on = !on;
                $(element).toggleClass('active', on);
            });
        }
    };
});

Existem algumas coisas erradas com isso:

  1. Primeiro, o jQuery nunca foi necessário. Não fizemos nada aqui que precisasse de jQuery!
  2. Segundo, mesmo se já tivermos o jQuery em nossa página, não há motivo para usá-lo aqui; podemos simplesmente usar angular.elemente nosso componente ainda funcionará quando inserido em um projeto que não possui jQuery.
  3. Terceiro, mesmo supondo que o jQuery fosse necessário para que essa diretiva funcionasse, o jqLite ( angular.element) sempre usará o jQuery se estiver carregado! Portanto, não precisamos usar o $- podemos apenas usar angular.element.
  4. Quarto, intimamente relacionado ao terceiro, é que os elementos jqLite não precisam ser envolvidos $- o elementque é passado para a linkfunção já seria um elemento jQuery!
  5. E quinto, que mencionamos nas seções anteriores, por que estamos misturando coisas de modelo em nossa lógica?

Essa diretiva pode ser reescrita (mesmo em casos muito complicados!) De maneira muito mais simples:

.directive( 'myDirective', function () {
    return {
        scope: true,
        template: '<a class="btn" ng-class="{active: on}" ng-click="toggle()">Toggle me!</a>',
        link: function ( scope, element, attrs ) {
            scope.on = false;

            scope.toggle = function () {
                scope.on = !scope.on;
            };
        }
    };
});

Novamente, o material do modelo está no modelo, para que você (ou seus usuários) possa trocá-lo facilmente por um que atenda a qualquer estilo necessário, e a lógica nunca precisou ser tocada. Reutilização - boom!

E ainda existem todos esses outros benefícios, como testes - é fácil! Independentemente do conteúdo do modelo, a API interna da diretiva nunca é tocada; portanto, a refatoração é fácil. Você pode alterar o modelo o quanto quiser sem tocar na diretiva. E não importa o que você mude, seus testes ainda passam.

w00t!

Portanto, se as diretivas não são apenas coleções de funções do tipo jQuery, o que são? Diretivas são realmente extensões de HTML . Se o HTML não fizer algo que você precisa, escreva uma diretiva para fazer isso por você e use-a como se fosse parte do HTML.

Dito de outra forma, se AngularJS não fazer algo fora da caixa, pense em como a equipe iria realizá-lo para caber perfeitamente com ngClick, ngClasset al.

Sumário

Nem use jQuery. Nem inclua. Isso vai te segurar. E quando você encontrar um problema que acha que já deve resolver no jQuery, antes de $procurar o , tente pensar em como fazê-lo dentro dos limites do AngularJS. Se você não sabe, pergunte! 19 de 20 vezes, a melhor maneira de fazer isso não precisa do jQuery e tentar resolvê-lo com os resultados do jQuery, resultando em mais trabalho para você.

Josh David Miller
fonte
204
Eu acho que incorporar o trabalho com o JQuery em um aplicativo angular é um caso de uso importante, devido a todos os plugins JQuery existentes que foram gravados. Não estou reescrevendo o FancyBox no jQuery para manter um aplicativo Angular puro.
26613 taudep
119
@taudep Eu não acho que discordamos tanto quanto você pensa. A maioria dos plugins jQuery pode ser reescrita no AngularJS de forma barata e, nesses casos, devemos fazê-lo. Para algo complexo para o qual não há um equivalente, tente. Para citar a Seção 2: 'O ponto principal é o seguinte: ao solucionar, primeiro "pense no AngularJS"; se você não consegue pensar em uma solução, pergunte à comunidade; se, depois de tudo isso, não houver uma solução fácil, fique à vontade para procurar o jQuery . Mas não deixe o jQuery se tornar uma muleta ou você nunca dominará o AngularJS. [ênfase adicionada]
Josh David Miller
67
um chinês traduz para esta ótima resposta, espero que seja útil. hanzheng.github.io/tech/angularjs/2013/10/28/...
Han Zheng
18
@ Benno O que ele quer dizer com "sem manipulação de DOM" é que seu código na diretiva não está executando diretamente manipulações de DOM. Esse código não sabe nada sobre o DOM, apenas modifica as variáveis ​​js no seu modelo. Sim, o resultado final é que o DOM é modificado, mas porque fora do código que escrevemos, existem ligações que reagem à alteração de nossas variáveis, mas dentro da diretiva não sabemos nada sobre isso, fazendo uma separação limpa entre a manipulação do DOM e logíca de negócios. No seu exemplo jQuery você está alterando diretamente o DOM dizendo "acrescentar este texto a este elemento"
wired_in
11
@trusktr Se um desenvolvimento definir o valor de um elemento de entrada usando jQuery em um aplicativo AngularJS, ele estará cometendo um erro grave . O único tipo de exceção que posso pensar é um plug-in jQuery existente que é muito difícil de portar e altera uma entrada automaticamente; nesse caso, conectar-se a um retorno de chamada ou definir um relógio é absolutamente essencial de qualquer maneira para trazer as alterações de acordo com o aplicativo.
Josh David Miller
407

Imperativo → declarativo

No jQuery, os seletores são usados ​​para encontrar elementos DOM e depois vincular / registrar manipuladores de eventos a eles. Quando um evento é acionado, esse código (imperativo) é executado para atualizar / alterar o DOM.

No AngularJS, você deseja pensar em visualizações em vez de elementos DOM. As visualizações são HTML (declarativo) que contêm diretivas AngularJS . As diretivas configuram os manipuladores de eventos nos bastidores e nos fornecem ligação dinâmica de dados. Os seletores raramente são usados, portanto, a necessidade de IDs (e alguns tipos de classes) é bastante reduzida. As visualizações estão vinculadas aos modelos (por escopos). As vistas são uma projeção do modelo. Eventos alteram modelos (ou seja, dados, propriedades do escopo) e as visualizações que projetam esses modelos são atualizadas "automaticamente".

No AngularJS, pense nos modelos, em vez dos elementos DOM selecionados pelo jQuery que mantêm seus dados. Pense nas visualizações como projeções desses modelos, em vez de registrar retornos de chamada para manipular o que o usuário vê.

Separação de preocupações

O jQuery emprega JavaScript discreto - o comportamento (JavaScript) é separado da estrutura (HTML).

O AngularJS usa controladores e diretivas (cada um dos quais pode ter seu próprio controlador e / ou funções de compilação e vinculação) para remover o comportamento da exibição / estrutura (HTML). A Angular também possui serviços e filtros para ajudar a separar / organizar seu aplicativo.

Consulte também https://stackoverflow.com/a/14346528/215945

Design da aplicação

Uma abordagem para projetar um aplicativo AngularJS:

  1. Pense nos seus modelos. Crie serviços ou seus próprios objetos JavaScript para esses modelos.
  2. Pense em como você deseja apresentar seus modelos - seus pontos de vista. Crie modelos HTML para cada visualização, usando as diretivas necessárias para obter a ligação de dados dinâmica.
  3. Anexe um controlador a cada visualização (usando ng-view and routing ou ng-controller). Faça com que o controlador encontre / obtenha apenas quaisquer dados do modelo que a exibição precise para fazer seu trabalho. Torne os controladores o mais fino possível.

Herança prototípica

Você pode fazer muito com o jQuery sem saber como funciona a herança prototípica do JavaScript. Ao desenvolver aplicativos AngularJS, você evitará algumas armadilhas comuns se tiver um bom entendimento da herança do JavaScript. Leitura recomendada: Quais são as nuances da herança prototípica / prototípica do escopo no AngularJS?

Mark Rajcok
fonte
1
você pode pls. explicar como um elemento dom é diferente de uma visualização?
Rajkamal Subramanian
22
@rajkamal, um elemento DOM é (obviamente) um único elemento, e no jQuery é frequentemente o que selecionamos / direcionamos / manipulamos. Uma visualização Angular é uma coleção / modelo de elementos DOM relacionados: visualização do menu, visualização do cabeçalho, visualização do rodapé, visualização da barra lateral direita, visualização do perfil, talvez várias visualizações principais de conteúdo (selecionáveis ​​através da visualização ng). Basicamente, você deseja dividir suas páginas em diferentes visualizações. Cada visualização possui seu próprio controlador associado. Cada visualização projeta parte dos seus modelos.
Mark Rajcok
3
jQuery NÃO é imperativo. one whensão funções de ordem superior, operando em membros de um objeto de coleção jQuery.
21713 Jack Viers
18
Então, para que tipo de código é executado o retorno de chamada on? Imperativo.
Cwharris
5
Esse imperativo versus declarativo é realmente apenas uma questão de abstrações. No final, todo o código declarativo (o que fazer) é implementado imperativamente (como fazê-lo) pelo desenvolvedor em uma sub-rotina em um nível de abstração mais baixo, pela estrutura ou por um compilador / intérprete. Dizer que "jQuery é imperativo" em geral é uma afirmação bastante estranha, especialmente considerando que ele realmente fornece uma API muito mais declarativa em relação à manipulação "manual" de DOM.
Alex
184

AngularJS vs. jQuery

AngularJS e jQuery adotam ideologias muito diferentes. Se você vem do jQuery, pode achar algumas das diferenças surpreendentes. Angular pode deixar você com raiva.

Isso é normal, você deve avançar. Angular vale a pena.

A grande diferença (TLDR)

O jQuery fornece um kit de ferramentas para selecionar bits arbitrários do DOM e fazer alterações ad-hoc neles. Você pode fazer praticamente qualquer coisa que desejar, peça por peça.

O AngularJS fornece um compilador .

O que isso significa é que o AngularJS lê todo o DOM de cima para baixo e o trata como código, literalmente como instruções para o compilador. À medida que atravessa o DOM, ele procura diretivas específicas ( diretivas do compilador) que informam ao compilador AngularJS como se comportar e o que fazer. As diretivas são pequenos objetos cheios de JavaScript que podem ser comparados com atributos, tags, classes ou mesmo comentários.

Quando o compilador Angular determina que uma parte do DOM corresponde a uma diretiva específica, ela chama a função diretiva, passando o elemento DOM, quaisquer atributos, o escopo $ atual (que é um armazenamento de variável local) e alguns outros bits úteis. Esses atributos podem conter expressões que podem ser interpretadas pela diretiva e que informam como renderizar e quando deve ser redesenhado.

As diretivas podem, por sua vez, extrair componentes angulares adicionais, como controladores, serviços etc. O que sai da parte inferior do compilador é um aplicativo da Web totalmente formado, conectado e pronto para uso.

Isso significa que Angular é acionado por modelo . Seu modelo direciona o JavaScript, e não o contrário. Essa é uma inversão radical de papéis, e o completo oposto do JavaScript discreto que escrevemos nos últimos 10 anos. Isso pode levar algum tempo para se acostumar.

Se isso parecer excessivamente prescritivo e limitador, nada poderá estar mais longe da verdade. Como o AngularJS trata seu HTML como código, você obtém granularidade no nível HTML em seu aplicativo da web . Tudo é possível, e a maioria das coisas é surpreendentemente fácil quando você dá alguns saltos conceituais.

Vamos ao âmago da questão.

Primeiro, Angular não substitui o jQuery

Angular e jQuery fazem coisas diferentes. O AngularJS fornece um conjunto de ferramentas para produzir aplicativos da web. O jQuery fornece principalmente ferramentas para modificar o DOM. Se o jQuery estiver presente na sua página, o AngularJS o usará automaticamente. Caso contrário, o AngularJS é enviado com o jQuery Lite, que é uma versão reduzida, mas ainda perfeitamente utilizável do jQuery.

Misko gosta de jQuery e não se opõe a você. No entanto, você descobrirá que, à medida que avança, pode realizar praticamente todo o seu trabalho usando uma combinação de escopo, modelos e diretivas, e deve preferir esse fluxo de trabalho sempre que possível, pois seu código será mais discreto, mais configurável e mais Angular.

Se você usa o jQuery, não deve espalhá-lo por todo o lado. O local correto para manipulação do DOM no AngularJS está em uma diretiva. Mais sobre isso mais tarde.

JavaScript discreto com seletores x modelos declarativos

O jQuery normalmente é aplicado de maneira discreta. Seu código JavaScript está vinculado no cabeçalho (ou no rodapé) e este é o único local em que é mencionado. Usamos seletores para selecionar partes da página e escrever plugins para modificar essas partes.

O JavaScript está no controle. O HTML tem uma existência completamente independente. Seu HTML permanece semântico mesmo sem JavaScript. Os atributos Onclick são uma prática muito ruim.

Uma das primeiras coisas que você notará sobre o AngularJS é que os atributos personalizados estão em toda parte . Seu HTML será repleto de atributos ng, que são essencialmente atributos onClick em esteróides. Essas são diretivas (diretivas do compilador) e são uma das principais maneiras pelas quais o modelo está conectado ao modelo.

Quando você vê isso pela primeira vez, pode se sentir tentado a escrever o AngularJS como JavaScript intrusivo da velha escola (como eu fiz no começo). De fato, o AngularJS não cumpre essas regras. No AngularJS, seu HTML5 é um modelo. É compilado pelo AngularJS para produzir sua página da web.

Esta é a primeira grande diferença. Para o jQuery, sua página da web é um DOM a ser manipulado. Para o AngularJS, seu HTML é um código a ser compilado. O AngularJS lê toda a sua página da Web e literalmente a compila em uma nova página da Web usando seu compilador incorporado.

Seu modelo deve ser declarativo; seu significado deve ficar claro simplesmente lendo-o. Usamos atributos personalizados com nomes significativos. Criamos novos elementos HTML, novamente com nomes significativos. Um designer com conhecimento mínimo em HTML e nenhuma habilidade de codificação pode ler seu modelo AngularJS e entender o que está fazendo. Ele ou ela pode fazer modificações. Este é o caminho angular.

O modelo está no banco do motorista.

Uma das primeiras perguntas que fiz a mim mesmo ao iniciar o AngularJS e executar os tutoriais é "Onde está o meu código?" . Não escrevi JavaScript e, no entanto, tenho todo esse comportamento. A resposta é óbvia. Como o AngularJS compila o DOM, o AngularJS está tratando seu HTML como código. Em muitos casos simples, geralmente basta escrever um modelo e permitir que o AngularJS o compile em um aplicativo para você.

Seu modelo direciona seu aplicativo. É tratado como um DSL . Você escreve componentes AngularJS, e o AngularJS se encarrega de puxá-los e disponibilizá-los no momento certo, com base na estrutura do seu modelo. Isso é muito diferente de um padrão MVC padrão, onde o modelo é apenas para saída.

É mais semelhante ao XSLT do que o Ruby on Rails, por exemplo.

Esta é uma inversão radical de controle que leva algum tempo para se acostumar.

Pare de tentar direcionar seu aplicativo a partir do JavaScript. Deixe o modelo dirigir o aplicativo e o AngularJS cuide da conexão dos componentes. Este também é o caminho angular.

Modelos semânticos vs. modelos semânticos

Com o jQuery, sua página HTML deve conter conteúdo semântico significativo. Se o JavaScript estiver desativado (por um usuário ou mecanismo de pesquisa), seu conteúdo permanecerá acessível.

Porque o AngularJS trata sua página HTML como um modelo. O modelo não deve ser semântico, pois seu conteúdo é normalmente armazenado em seu modelo, que em última análise vem da sua API. O AngularJS compila seu DOM com o modelo para produzir uma página da web semântica.

Sua fonte HTML não é mais semântica; em vez disso, sua API e o DOM compilado são semânticos.

No AngularJS, o significado está no modelo, o HTML é apenas um modelo, apenas para exibição.

Nesse ponto, você provavelmente tem todo tipo de perguntas sobre SEO e acessibilidade, e com razão. Existem questões em aberto aqui. A maioria dos leitores de tela agora analisará o JavaScript. Os mecanismos de pesquisa também podem indexar o conteúdo AJAX . No entanto, convém garantir que você esteja usando URLs pushstate e tenha um mapa do site decente. Veja aqui uma discussão sobre o problema: https://stackoverflow.com/a/23245379/687677

Separação de preocupações (SOC) vs. MVC

A separação de preocupações (SOC) é um padrão que cresceu ao longo de muitos anos de desenvolvimento da web por vários motivos, incluindo SEO, acessibilidade e incompatibilidade do navegador. Se parece com isso:

  1. HTML - significado semântico. O HTML deve estar sozinho.
  2. CSS - Estilo, sem o CSS, a página ainda pode ser lida.
  3. JavaScript - Comportamento, sem o script, o conteúdo permanece.

Novamente, o AngularJS não segue suas regras. Em um golpe, o AngularJS acaba com uma década de sabedoria recebida e implementa um padrão MVC no qual o modelo não é mais semântico, nem um pouco.

Se parece com isso:

  1. Modelo - seus modelos contêm seus dados semânticos. Modelos são geralmente objetos JSON . Os modelos existem como atributos de um objeto chamado $ scope. Você também pode armazenar funções úteis no $ scope, que seus modelos podem acessar.
  2. Ver - Suas visualizações são escritas em HTML. A visualização geralmente não é semântica porque seus dados residem no modelo.
  3. Controlador - Seu controlador é uma função JavaScript que conecta a visualização ao modelo. Sua função é inicializar $ scope. Dependendo do seu aplicativo, você pode ou não precisar criar um controlador. Você pode ter muitos controladores em uma página.

MVC e SOC não estão em extremos opostos da mesma escala, eles estão em eixos completamente diferentes. O SOC não faz sentido em um contexto do AngularJS. Você tem que esquecer e seguir em frente.

Se, como eu, você viveu a guerra dos navegadores, pode achar essa ideia bastante ofensiva. Supere isso, valerá a pena, eu prometo.

Plugins vs. Diretivas

Os plug-ins estendem o jQuery. As Diretivas AngularJS ampliam os recursos do seu navegador.

No jQuery, definimos plugins adicionando funções ao jQuery.prototype. Em seguida, os conectamos ao DOM selecionando elementos e chamando o plug-in no resultado. A idéia é ampliar os recursos do jQuery.

Por exemplo, se você deseja um carrossel em sua página, pode definir uma lista não ordenada de figuras, talvez agrupada em um elemento nav. Você pode escrever um jQuery para selecionar a lista na página e reestilizá-la como uma galeria com tempos limite para executar a animação deslizante.

No AngularJS, definimos diretivas. Uma diretiva é uma função que retorna um objeto JSON. Este objeto informa ao AngularJS quais elementos do DOM procurar e quais alterações fazer neles. As diretivas são conectadas ao modelo usando atributos ou elementos que você inventa. A idéia é estender os recursos do HTML com novos atributos e elementos.

A maneira AngularJS é estender os recursos do HTML com aparência nativa. Você deve escrever HTML parecido com HTML, estendido com atributos e elementos personalizados.

Se você deseja um carrossel, basta usar um <carousel />elemento, em seguida, defina uma diretiva para inserir um modelo e faça esse otário funcionar.

Muitas diretivas pequenas x plugins grandes com comutadores de configuração

A tendência com o jQuery é escrever grandes plugins como o lightbox que, em seguida, configuramos passando vários valores e opções.

Este é um erro no AngularJS.

Veja o exemplo de uma lista suspensa. Ao escrever um plug-in suspenso, você pode ser tentado a codificar em manipuladores de cliques, talvez uma função para adicionar uma divisa que está para cima ou para baixo, talvez mude a classe do elemento desdobrado, mostre o menu oculto, todas as coisas úteis.

Até que você queira fazer uma pequena alteração.

Digamos que você tenha um menu que deseja desdobrar ao passar o mouse. Bem, agora temos um problema. Nosso plug-in foi conectado ao nosso manipulador de cliques para nós, precisaremos adicionar uma opção de configuração para que ele se comporte de maneira diferente nesse caso específico.

No AngularJS, escrevemos diretivas menores. Nossa diretiva suspensa seria ridiculamente pequena. Pode manter o estado dobrado e fornecer métodos para dobrar (), desdobrar () ou alternar (). Esses métodos simplesmente atualizariam $ scope.menu.visible, que é um booleano que contém o estado.

Agora, em nosso modelo , podemos conectar isso:

<a ng-click="toggle()">Menu</a>
<ul ng-show="menu.visible">
  ...
</ul>

Precisa atualizar sobre o mouseover?

<a ng-mouseenter="unfold()" ng-mouseleave="fold()">Menu</a>
<ul ng-show="menu.visible">
  ...
</ul>

O modelo direciona o aplicativo para obter granularidade no nível HTML. Se queremos criar exceções caso a caso, o modelo facilita isso.

Encerramento vs. $ escopo

Os plugins JQuery são criados em um fechamento. A privacidade é mantida dentro desse fechamento. Cabe a você manter sua cadeia de escopo dentro desse fechamento. Você realmente só tem acesso ao conjunto de nós DOM transmitidos ao plugin pelo jQuery, além de quaisquer variáveis ​​locais definidas no fechamento e quaisquer globais que você definiu. Isso significa que os plugins são bastante independentes. Isso é bom, mas pode ser restritivo ao criar um aplicativo inteiro. Tentar passar dados entre seções de uma página dinâmica se torna uma tarefa árdua.

AngularJS possui objetos $ scope. Esses são objetos especiais criados e mantidos pelo AngularJS nos quais você armazena seu modelo. Certas diretivas geram um novo escopo $, que por padrão herda de seu escopo $ empacotado usando herança prototípica JavaScript. O objeto $ scope está acessível no controlador e na visualização.

Esta é a parte inteligente. Como a estrutura da herança $ scope segue aproximadamente a estrutura do DOM, os elementos têm acesso ao seu próprio escopo e a qualquer escopo que contenha perfeitamente, até o escopo global $ (que não é o mesmo que o escopo global).

Isso facilita muito a transmissão de dados e o armazenamento em um nível apropriado. Se um menu suspenso for desdobrado, apenas o escopo $ do menu suspenso precisará saber sobre ele. Se o usuário atualizar suas preferências, convém atualizar o escopo $ global, e quaisquer escopos aninhados que atendam às preferências do usuário serão alertados automaticamente.

Isso pode parecer complicado, de fato, uma vez que você relaxa, é como voar. Você não precisa criar o objeto $ scope, o AngularJS o instancia e configura para você, correta e adequadamente, com base na sua hierarquia de modelos. O AngularJS então o torna disponível para o seu componente usando a mágica da injeção de dependência (mais sobre isso mais adiante).

Alterações manuais do DOM vs. vinculação de dados

No jQuery, você faz todas as alterações do DOM manualmente. Você constrói novos elementos DOM programaticamente. Se você possui uma matriz JSON e deseja colocá-la no DOM, deve escrever uma função para gerar o HTML e inseri-lo.

No AngularJS, você também pode fazer isso, mas é incentivado a usar a ligação de dados. Altere seu modelo e, como o DOM está vinculado a ele por meio de um modelo, o DOM será atualizado automaticamente, sem necessidade de intervenção.

Como a ligação de dados é feita a partir do modelo, usando um atributo ou a sintaxe de chaves, é super fácil de fazer. Há pouca sobrecarga cognitiva associada a isso, então você se encontrará fazendo isso o tempo todo.

<input ng-model="user.name" />

Vincula o elemento de entrada a $scope.user.name. A atualização da entrada atualizará o valor no seu escopo atual e vice-versa.

Da mesma forma:

<p>
  {{user.name}}
</p>

produzirá o nome de usuário em um parágrafo. É uma ligação ativa, portanto, se o $scope.user.namevalor for atualizado, o modelo também será atualizado.

Ajax o tempo todo

No jQuery, fazer uma chamada Ajax é bastante simples, mas ainda é algo em que você pode pensar duas vezes. Há uma complexidade adicional para se pensar e um bom pedaço de script para manter.

No AngularJS, o Ajax é sua solução padrão e acontece o tempo todo, quase sem você perceber. Você pode incluir modelos com ng-include. Você pode aplicar um modelo com a diretiva personalizada mais simples. Você pode encerrar uma chamada Ajax em um serviço e criar um serviço GitHub , ou um serviço Flickr , que você pode acessar com uma facilidade surpreendente.

Objetos de serviço x funções auxiliares

No jQuery, se queremos realizar uma pequena tarefa não relacionada ao domínio, como extrair um feed de uma API, podemos escrever uma pequena função para fazer isso em nosso encerramento. Essa é uma solução válida, mas e se quisermos acessar esse feed com frequência? E se quisermos reutilizar esse código em outro aplicativo?

AngularJS nos fornece objetos de serviço.

Serviços são objetos simples que contêm funções e dados. Eles são sempre singletons, o que significa que nunca pode haver mais de um deles. Digamos que desejamos acessar a API Stack Overflow, podemos escrever um StackOverflowServiceque defina métodos para isso.

Digamos que temos um carrinho de compras. Podemos definir um ShoppingCartService que mantém nosso carrinho e contém métodos para adicionar e remover itens. Como o serviço é um singleton e é compartilhado por todos os outros componentes, qualquer objeto que precise pode gravar no carrinho de compras e extrair dados dele. É sempre o mesmo carrinho.

Objetos de serviço são componentes independentes do AngularJS que podemos usar e reutilizar como acharmos melhor. Eles são objetos JSON simples que contêm funções e dados. Eles sempre são singletons; portanto, se você armazenar dados em um serviço em um local, poderá obtê-los em outro lugar apenas solicitando o mesmo serviço.

Injeção de Dependência (DI) vs. Instatiação - aka des-spaghettification

O AngularJS gerencia suas dependências para você. Se você deseja um objeto, basta consultá-lo e o AngularJS o obterá para você.

Até você começar a usar isso, é difícil explicar o quanto esse benefício é massivo. Nada como o AngularJS DI existe dentro do jQuery.

DI significa que, em vez de escrever seu aplicativo e conectá-lo, você define uma biblioteca de componentes, cada um identificado por uma sequência.

Digamos que eu tenha um componente chamado 'FlickrService', que define métodos para obter feeds JSON do Flickr. Agora, se eu quiser escrever um controlador que possa acessar o Flickr, só preciso me referir ao 'FlickrService' por nome quando declarar o controlador. O AngularJS cuidará de instanciar o componente e disponibilizá-lo ao meu controlador.

Por exemplo, aqui eu defino um serviço:

myApp.service('FlickrService', function() {
  return {
    getFeed: function() { // do something here }
  }
});

Agora, quando eu quero usar esse serviço, apenas me refiro a ele por nome como este:

myApp.controller('myController', ['FlickrService', function(FlickrService) {
  FlickrService.getFeed()
}]);

O AngularJS reconhecerá que um objeto FlickrService é necessário para instanciar o controlador e fornecerá um para nós.

Isso facilita muito a conexão das coisas e elimina praticamente qualquer tendência à spagetificação. Temos uma lista simples de componentes e o AngularJS os entrega um a um quando e quando precisamos deles.

Arquitetura de serviço modular

O jQuery diz muito pouco sobre como você deve organizar seu código. AngularJS tem opiniões.

O AngularJS fornece módulos nos quais você pode inserir seu código. Se você estiver escrevendo um script que fale com o Flickr, por exemplo, convém criar um módulo do Flickr para envolver todas as suas funções relacionadas ao Flickr. Os módulos podem incluir outros módulos (DI). Seu aplicativo principal geralmente é um módulo e isso deve incluir todos os outros módulos dos quais seu aplicativo dependerá.

Você obtém uma reutilização simples de código. Se quiser escrever outro aplicativo baseado no Flickr, basta incluir o módulo Flickr e pronto, você terá acesso a todas as funções relacionadas ao Flickr em seu novo aplicativo.

Os módulos contêm componentes AngularJS. Quando incluímos um módulo, todos os componentes desse módulo ficam disponíveis para nós como uma lista simples identificada por suas seqüências únicas . Podemos injetar esses componentes um no outro usando o mecanismo de injeção de dependência do AngularJS.

Resumindo

AngularJS e jQuery não são inimigos. É possível usar o jQuery dentro do AngularJS muito bem. Se você estiver usando bem o AngularJS (modelos, vinculação de dados, $ scope, diretivas etc.), descobrirá que precisa de muito menos jQuery do que poderia exigir.

A principal coisa a perceber é que seu modelo direciona seu aplicativo. Pare de tentar escrever grandes plugins que fazem tudo. Em vez disso, escreva pequenas diretivas que fazem uma coisa e, em seguida, escreva um modelo simples para conectá-las.

Pense menos em JavaScript discreto e, em vez disso, pense em termos de extensões HTML.

Meu livrinho

Fiquei tão empolgado com o AngularJS que escrevi um pequeno livro sobre ele, que você pode ler on-line http://nicholasjohnson.com/angular-book/ . Espero que seja útil.

superluminário
fonte
6
A idéia de que "Separação de preocupações" é diferente de "MVC (Model, View, Controller)" é totalmente falsa. O modelo de linguagens da web para separar preocupações (HTML, CSS e JS) permite que as pessoas coloquem coisas em uma página da web (a marcação / HTML) sem se preocupar com a aparência (estilo / layout / CSS) ou o que "faz" (Eventos DOM / AJAX / JavaScript). O MVC também separa as preocupações. Cada "camada" no padrão MVC tem uma função distinta - dados, roteamento / lógica ou renderização. As camadas são acopladas por retornos de chamada, rotas e ligações de modelo. Em teoria, uma pessoa pode se especializar em cada camada, o que geralmente é o caso.
Como alguém proveniente de um histórico estrito do SOC e defensor de longa data dos padrões da Web desde a guerra dos navegadores, inicialmente achei os modelos não-semânticos e não-validadores da Angular problemáticos. Eu só queria deixar claro que, para escrever Angular, é necessário abandonar o SOC, como geralmente é praticado. Esta pode ser uma transição difícil.
superluminary
Você está certo. SOC é um termo amplo, mas no mundo da web o SOC tem (ou possivelmente teve) um significado muito específico: HTML semântico, CSS de apresentação e JavaScript para comportamento. Estou fazendo algumas suposições sobre o meu público que talvez não sejam razoáveis, por isso devo pedir desculpas também.
superluminary
Acho sua resposta mais clara e esclarecedora. Sou um novato aqui, então, se eu tiver uma extensão para alterar uma página existente (que não controlo), devo manter o JQuery?
Daniel Möller
152

Você pode descrever a mudança de paradigma necessária?

Imperativo vs Declarativo

Com o jQuery, você informa ao DOM o que precisa acontecer, passo a passo. Com o AngularJS, você descreve quais resultados deseja, mas não como fazê-lo. Mais sobre isso aqui . Além disso, confira a resposta de Mark Rajcok.

Como faço para projetar e projetar aplicativos da Web do lado do cliente de maneira diferente?

O AngularJS é uma estrutura inteira do lado do cliente que usa o padrão MVC (confira sua representação gráfica ). Ele se concentra muito na separação de preocupações.

Qual é a maior diferença? O que devo parar de fazer / usar; o que devo começar a fazer / usar?

jQuery é uma biblioteca

O AngularJS é uma bela estrutura do lado do cliente, altamente testável, que combina toneladas de coisas interessantes, como MVC, injeção de dependência , ligação de dados e muito mais.

Ele se concentra na separação de preocupações e testes (testes de unidade e testes de ponta a ponta), o que facilita o desenvolvimento orientado a testes.

A melhor maneira de começar é seguir o incrível tutorial . Você pode seguir as etapas em algumas horas; no entanto, caso você queira dominar os conceitos nos bastidores, eles incluem uma infinidade de referências para leitura adicional.

Existem considerações / restrições do lado do servidor?

Você pode usá-lo em aplicativos existentes onde você já está usando jQuery puro. No entanto, se você quiser aproveitar ao máximo os recursos do AngularJS, considere codificar o lado do servidor usando um RESTful abordagem .

Isso permitirá que você aproveite a fábrica de recursos , o que cria uma abstração da API RESTful do lado do servidor e facilita incrivelmente as chamadas do lado do servidor (obter, salvar, excluir etc.).

Ulises
fonte
27
Eu acho que você está confundindo as águas falando sobre como o jQuery é uma "biblioteca" e o Angular é uma "estrutura" ... por um lado, acho que é possível argumentar que o jQuery é uma estrutura ... é uma abstração manipulação de DOM e manipulação de eventos. Pode não ser uma estrutura para o mesmo tipo de coisa que o Angular é, mas esse é o dilema em que o questionador se encontra: eles realmente não sabem a diferença entre Angular e jQuery e, pelo que todo o questionador sabe, o jQuery é uma estrutura para criar sites pesados ​​para o cliente. Portanto, discutir sobre terminologia não esclarecerá as coisas.
Zando
15
Eu acho que você é quem está ficando confuso. Esta pergunta aborda exatamente esse stackoverflow.com/questions/7062775 . Além disso, esta resposta pode ajudar a esclarecer qual é a diferença entre uma estrutura e uma biblioteca: stackoverflow.com/a/148759/620448
Ulises
6
Uma biblioteca não se torna uma "estrutura" apenas porque sua coleção de funções é especialmente útil ou grande. Uma estrutura toma decisões para você. Quando você começa a usar o AngularJS, é provável que fique acoplado a ele por sua natureza. (Por exemplo: você só deve atualizar o DOM nas diretivas, caso contrário, algo irá atrapalhar.) Isso ocorre porque o AngularJS é uma estrutura. Ao usar o jQuery, você pode misturar e combinar ferramentas com relativa facilidade, com risco mínimo de conflito. Isso ocorre porque o jQuery é uma biblioteca e pelo menos meio decente também.
8
Uma biblioteca é o código que você chama. Uma estrutura é um código que chama seu código. Por essa definição, Angular é uma estrutura. Você o fornece componentes e o Angular garante que seus componentes sejam instanciados com as dependências de que precisam.
superluminary
84

Para descrever a "mudança de paradigma", acho que uma resposta curta pode ser suficiente.

AngularJS muda a maneira como você encontra elementos

No jQuery , você normalmente usa seletores para encontrar elementos e os conecta:
$('#id .class').click(doStuff);

No AngularJS , você usa diretivas para marcar os elementos diretamente, para conectá-los:
<a ng-click="doStuff()">

Não AngularJS não precisa (ou quer)-lo a encontrar elementos usando seletores - a principal diferença entre das AngularJS jqLite contra full-blown jQuery é que jqLite não suporta seletores .

Portanto, quando as pessoas dizem "não incluem jQuery", é principalmente porque elas não querem que você use seletores; eles querem que você aprenda a usar diretivas. Direto, não selecione!

Scott Rippey
fonte
13
Apenas como um aviso, existem MUITAS maiores diferenças entre Angular e jQuery. Mas encontrar elementos é o que requer a maior mudança de pensamento.
Scott Rippey
1
perdoe-me se eu estiver errado, mas pensei que era um seletor que você usa para encontrar o elemento DOM? Você prefere manter todas as partes da interface do usuário recém-carregada em referência, em vez de simplesmente selecionar os um ou dois elementos nos quais um usuário pode clicar em tempo real usando um seletor? sons mais difíceis para mim ..
ROZZA
3
@AlexanderPritchard O ponto de Angular é que você não seleciona no seu JavaScript, você direciona a partir do seu modelo. É uma inversão de controle que coloca o poder nas mãos do designer. Este é um princípio de design deliberado. Para realmente obter o Angular, você precisa pensar no seu código dessa maneira. É uma mudança difícil de fazer.
superluminary
3
@ superluminary Que ótima citação! "não selecione; direto!" Sério, eu vou usar isso.
Scott Rippey
1
Esta é uma das minhas coisas favoritas sobre o AngularJS. Não preciso me preocupar com a equipe de UX quebrando minha funcionalidade ou comigo quebrando seus estilos. Eles usam aulas, eu uso diretivas, ponto final. Não sinto falta dos seletores nem um pouco.
precisa saber é o seguinte
69

jQuery

O jQuery faz comandos JavaScript ridiculamente longos, como getElementByHerpDerpcurtos e entre navegadores.

AngularJS

O AngularJS permite criar suas próprias tags / atributos HTML que funcionam bem com aplicativos dinâmicos da Web (desde que o HTML foi projetado para páginas estáticas).

Editar:

Dizendo "Tenho experiência em jQuery, como penso no AngularJS?" é como dizer "Tenho um background em HTML, como penso em JavaScript?" O fato de você estar fazendo a pergunta mostra que provavelmente não entende os propósitos fundamentais desses dois recursos. É por isso que escolhi responder à pergunta simplesmente apontando a diferença fundamental, em vez de passar pela lista dizendo "AngularJS faz uso de diretivas, enquanto o jQuery usa seletores CSS para criar um objeto jQuery que faz isso e aquilo etc ..." . Esta pergunta não requer uma resposta longa.

O jQuery é uma maneira de facilitar a programação do JavaScript no navegador. Comandos mais curtos entre navegadores, etc.

O AngularJS estende o HTML, para que você não precise colocar <div>todo o lugar apenas para criar um aplicativo. Faz com que o HTML realmente funcione para aplicativos, e não para o que foi projetado, que é estático, páginas da Web educacionais. Isso é feito de maneira indireta usando JavaScript, mas fundamentalmente é uma extensão do HTML, não do JavaScript.

Nick Manning
fonte
@ Robert depende do que você está fazendo. $(".myclass")é extremamente comum e mais do que um pouco mais fácil no jQuery do que no PO-Javascript.
Rob Grant
61

jQuery: você pensa muito em 'Consultar o DOM ' para elementos DOM e fazer alguma coisa.

AngularJS: O modelo é a verdade, e você sempre pensa nesse ângulo.

Por exemplo, quando você obtém dados do servidor que pretende exibir em algum formato no DOM, no jQuery, você precisa '1. FIND 'onde no DOM você deseja colocar esses dados, o' 2. UPDATE / APPEND 'lá, criando um novo nó ou apenas configurando seu innerHTML . Então, quando você deseja atualizar esta exibição, você '3. ENCONTRE 'a localização e' 4. ATUALIZAR'. Esse ciclo de localização e atualização, realizado no mesmo contexto de obtenção e formatação de dados do servidor, ocorre no AngularJS.

Com o AngularJS, você tem seu modelo (objetos JavaScript com os quais você já está acostumado) e o valor do modelo informa sobre o modelo (obviamente) e sobre a visualização, e uma operação no modelo se propaga automaticamente para a visualização, para que você não Não tenho que pensar sobre isso. Você se encontrará no AngularJS e não encontra mais coisas no DOM.

Em outras palavras, no jQuery, é necessário pensar nos seletores de CSS, ou seja, onde é divou tdque tem uma classe ou atributo etc., para que eu possa obter o HTML, a cor ou o valor, mas no AngularJS, você se verá pensando assim: com qual modelo estou lidando, definirei o valor do modelo como verdadeiro. Você não está se preocupando se a exibição que reflete esse valor é uma caixa marcada ou reside em um tdelemento (detalhes que você frequentemente precisaria pensar no jQuery).

E com a manipulação do DOM no AngularJS, você adiciona diretivas e filtros, que podem ser considerados extensões HTML válidas.

Mais uma coisa que você experimentará no AngularJS: no jQuery, você chama muito as funções do jQuery; no AngularJS, o AngularJS chama suas funções; portanto, o AngularJS 'diz a você como fazer as coisas', mas os benefícios valem a pena, então, aprender o AngularJS geralmente significa aprender o que o AngularJS quer ou a maneira como o AngularJS exige que você apresente suas funções e ele será chamado de acordo. Essa é uma das coisas que faz do AngularJS uma estrutura e não uma biblioteca.

Samuel
fonte
46

Essas são algumas respostas muito legais, mas longas.

Para resumir minhas experiências:

  1. Controladores e provedores (serviços, fábricas etc.) são para modificar o modelo de dados, NÃO HTML.
  2. HTML e diretivas definem o layout e a ligação ao modelo.
  3. Se você precisar compartilhar dados entre controladores, crie um serviço ou fábrica - eles são singletons compartilhados pelo aplicativo.
  4. Se você precisar de um widget HTML, crie uma diretiva.
  5. Se você possui alguns dados e agora está tentando atualizar o HTML ... PARE! atualize o modelo e verifique se o seu HTML está vinculado ao modelo.
Dan
fonte
45

jQuery é uma biblioteca de manipulação de DOM.

AngularJS é uma estrutura MV *.

De fato, o AngularJS é uma das poucas estruturas JavaScript MV * (muitas ferramentas JavaScript MVC ainda se enquadram na biblioteca de categorias).

Sendo uma estrutura, ele hospeda seu código e toma posse de decisões sobre o que chamar e quando!

O próprio AngularJS inclui uma edição do jQuery-lite. Portanto, para algumas seleções / manipulações básicas do DOM, você realmente não precisa incluir a biblioteca jQuery (ela economiza muitos bytes para rodar na rede).

O AngularJS possui o conceito de "Diretivas" para manipulação do DOM e o design de componentes reutilizáveis ​​da interface do usuário; portanto, você deve usá-lo sempre que sentir necessidade de fazer coisas relacionadas à manipulação do DOM (as diretivas são apenas um local onde você deve escrever o código jQuery ao usar o AngularJS).

O AngularJS envolve alguma curva de aprendizado (mais do que jQuery :-).

-> Para qualquer desenvolvedor que tenha experiência com jQuery, meu primeiro conselho seria "aprender JavaScript como uma linguagem de primeira classe antes de saltar para uma estrutura rica como o AngularJS!" Eu aprendi o fato acima da maneira mais difícil.

Boa sorte.

Anand
fonte
34

São maçãs e laranjas. Você não quer compará-los. São duas coisas diferentes. O AngularJs já possui o jQuery lite embutido, que permite executar a manipulação básica do DOM sem incluir a versão completa do jQuery.

jQuery é tudo sobre manipulação de DOM. Ele resolve todos os problemas de vários navegadores, caso contrário você terá que lidar com isso, mas não é uma estrutura que permita dividir seu aplicativo em componentes como o AngularJS.

Uma coisa boa do AngularJs é que ele permite separar / isolar a manipulação do DOM nas diretivas. Existem diretivas internas prontas para você usar, como o ng-click. Você pode criar suas próprias diretivas personalizadas que conterão toda a lógica de exibição ou manipulação de DOM, para não misturar o código de manipulação de DOM nos controladores ou serviços que devem cuidar da lógica de negócios.

Angular divide seu aplicativo em - Controladores - Serviços - Exibições - etc.

e há mais uma coisa, essa é a diretiva. É um atributo que você pode anexar a qualquer elemento DOM e pode ficar louco com o jQuery dentro dele, sem se preocupar com o fato de seu jQuery entrar em conflito com os componentes do AngularJs ou atrapalhar sua arquitetura.

Soube de um encontro em que participei, um dos fundadores da Angular disse que se esforçou muito para separar a manipulação do DOM, portanto, não tente incluí-los novamente.

Jin
fonte
31

Ouça o podcast JavaScript Jabber: Episode # 32, que apresenta os criadores originais de AngularJS: Misko Hevery e Igor Minar. Eles falam muito sobre como é o AngularJS de outras origens JavaScript, especialmente o jQuery.

Um dos pontos levantados no podcast fez muitas coisas clicar para mim com relação à sua pergunta:

MISKO : [...] uma das coisas em que pensamos muito pouco em Angular é: como fornecemos muitas escotilhas de escape para que você possa sair e basicamente descobrir uma maneira de sair disso. Então, para nós, a resposta é essa coisa chamada “Diretivas”. E com as diretivas, você basicamente se torna um pequeno JavaScript jQuery comum, e pode fazer o que quiser.

IGOR : Pense na diretiva como a instrução para o compilador que a informa sempre que você encontra esse elemento ou CSS no modelo e mantém esse tipo de código e esse código é responsável pelo elemento e tudo abaixo desse elemento na árvore DOM.

Uma transcrição de todo o episódio está disponível no link fornecido acima.

Portanto, para responder diretamente à sua pergunta: AngularJS é muito opinativo e é uma verdadeira estrutura MV *. No entanto, você ainda pode fazer todo o material interessante que você conhece e ama com o jQuery dentro das diretivas. Não se trata de "Como faço o que costumava fazer no jQuery?" tanto quanto é uma questão de "Como suplementar o AngularJS com todas as coisas que costumava fazer no jQuery?"

São realmente dois estados de espírito muito diferentes.

codevinsky
fonte
2
Não tenho certeza se concordo que Angular é MUITO opinativo. Você quer opinar, olhe para Ember. Eu retrataria o Angular como tendo opiniões negras - por muito do que vejo, o jQuery tem poucas opiniões e Ember, muitas. Angular parece certo.
22414 t4jesus
30

Acho essa pergunta interessante, porque minha primeira exposição séria à programação JavaScript foi o Node.js e o AngularJS. Eu nunca aprendi jQuery e acho que é uma coisa boa, porque não preciso desaprender nada. Na verdade, evito ativamente soluções jQuery para meus problemas e, em vez disso, procuro apenas uma "maneira AngularJS" para resolvê-los. Portanto, acho que minha resposta a essa pergunta se resumia essencialmente a "pense como alguém que nunca aprendeu jQuery" e evite qualquer tentação de incorporar o jQuery diretamente (obviamente o AngularJS o usa até certo ponto nos bastidores).

Evan Zamir
fonte
23

AngularJS e jQuery:

AngularJs e JQuery são completamente diferentes em todos os níveis, exceto a funcionalidade JQLite, e você o verá quando começar a aprender os principais recursos do AngularJs (expliquei abaixo).

AngularJs é uma estrutura do lado do cliente que oferece a construção do aplicativo independente do lado do cliente. JQuery é uma biblioteca do lado do cliente que brinca com o DOM.

Princípio legal de AngularJs - Se você quiser algumas alterações em sua interface do usuário, pense na perspectiva de mudança de dados do modelo. Altere seus dados e a interface do usuário será renderizada novamente. Você não precisa brincar com o DOM todas as vezes, a menos e até que seja pouco exigido e que também deva ser tratado pelas Diretivas Angulares.

Para responder a essa pergunta, quero compartilhar minha experiência no primeiro aplicativo corporativo com o AngularJS. Esses são os recursos mais impressionantes que o Angular fornece, onde começamos a mudar nossa mentalidade jQuery e obtemos o Angular como uma estrutura e não a biblioteca.

A ligação de dados bidirecional é incrível: eu tinha uma grade com todas as funcionalidades UPDATE, DELTE, INSERT. Eu tenho um objeto de dados que liga o modelo da grade usando ng-repeat. Você só precisa escrever uma única linha de código JavaScript simples para excluir e inserir e é isso. a grade é atualizada automaticamente conforme o modelo da grade muda instantaneamente. A funcionalidade de atualização é em tempo real, sem código. Você se sente incrível!!!

Diretivas reutilizáveis ​​são super: escreva diretivas em um só lugar e use-as em todo o aplicativo. AMD!!! Eu usei essas diretivas para paginação, regex, validações, etc. É muito legal!

O roteamento é forte: depende da sua implementação como você deseja usá-lo, mas requer muito poucas linhas de código para rotear a solicitação para especificar HTML e controlador (JavaScript)

Os controladores são ótimos: controladores cuidam de seu próprio HTML, mas essa separação funciona bem para funcionalidades comuns também. Se você quiser chamar a mesma função com o clique de um botão no HTML principal, basta escrever o mesmo nome da função em cada controlador e escrever um código individual.

Plug-ins: existem muitos outros recursos semelhantes, como mostrar uma sobreposição no seu aplicativo. Você não precisa escrever código para isso, basta usar um plug-in de sobreposição disponível como wc-overlay, e isso cuidará automaticamente de todas as solicitações XMLHttpRequest (XHR).

Ideal para arquitetura RESTful : Ser uma estrutura completa torna o AngularJS ótimo para trabalhar com uma arquitetura RESTful. Chamar APIs REST CRUD é muito mais fácil e

Serviços : Escreva códigos comuns usando serviços e menos código nos controladores. Os serviços podem ser usados ​​para compartilhar funcionalidades comuns entre os controladores.

Extensibilidade : Angular estendeu as diretivas HTML usando diretivas angulares. Escreva expressões dentro do html e avalie-as no tempo de execução. Crie suas próprias diretivas e serviços e use-os em outro projeto sem nenhum esforço extra.

Sanjeev Singh
fonte
20

Como iniciante em JavaScript MV * e focando puramente na arquitetura do aplicativo (não importa o lado do servidor / cliente), eu certamente recomendaria o seguinte recurso (que me surpreende ainda não ter sido mencionado): JavaScript Design Patterns , por Addy Osmani , como uma introdução aos diferentes padrões de design do JavaScript . Os termos usados ​​nesta resposta são retirados do documento vinculado acima. Não vou repetir muito bem o que foi redigido na resposta aceita. Em vez disso, esta resposta está vinculada ao antecedentes teóricos que alimentam o AngularJS (e outras bibliotecas).

Como eu, você logo perceberá que AngularJS (ou Ember.js , Durandal e outras estruturas MV *) é uma estrutura complexa que reúne muitos dos diferentes padrões de design do JavaScript.

Também achei mais fácil testar (1) código JavaScript nativo e (2) bibliotecas menores para cada um desses padrões separadamente antes de mergulhar em uma estrutura global. Isso me permitiu entender melhor quais questões cruciais uma estrutura aborda (porque você enfrenta pessoalmente o problema).

Por exemplo:

  • Programação orientada a objetos JavaScript (este é um link de pesquisa do Google). Não é uma biblioteca, mas certamente um pré-requisito para qualquer programação de aplicativo. Ele me ensinou as implementações nativas do padrões de protótipo, construtor, singleton e decorador
  • jQuery / sublinhado para o padrão de fachada (como WYSIWYG para manipular o DOM)
  • Prototype.js para o padrão prototype / constructor / mixin
  • RequireJS / Curl.js para o padrão de módulo / AMD
  • KnockoutJS para o padrão observável de publicação / assinatura

NB: Esta lista não está completa, nem 'as melhores bibliotecas'; elas são as bibliotecas que eu usei. Essas bibliotecas também incluem mais padrões, os mencionados são apenas seus principais focos ou intenções originais. Se você sentir que algo está faltando nessa lista, mencione-o nos comentários e terei prazer em adicioná-lo.

Tyblitz
fonte
12

Na verdade, se você estiver usando o AngularJS, não precisará mais do jQuery. O próprio AngularJS possui a ligação e a diretiva, que são uma "substituição" muito boa para a maioria das coisas que você pode fazer com o jQuery.

Geralmente desenvolvo aplicativos móveis usando AngularJS e Cordova . A única coisa do jQuery que eu precisava é o seletor.

Ao pesquisar no Google, vejo que existe um módulo seletor jQuery independente por aí. É Sizzle.

E decidi criar um pequeno trecho de código que me ajudaria a iniciar rapidamente um site usando o AngularJS com o poder do jQuery Selector (usando o Sizzle).

Compartilhei meu código aqui: https://github.com/huytd/Sizzular

Huy Tran
fonte