今日已更新 305 条资讯 | 累计 19865 条内容
关于我们

标签:#angular

找到 20 篇相关文章

AI 资讯

Build Firebase AI Logic Application with Antigravity CLI and Stitch MCP Server [GDE]

Build Firebase AI Logic with Antigravity CLI Note: Google Cloud credits are provided for this project. In this blog post, I demonstrate how to use the Antigravity CLI (an agentic AI assistant integrating directly with development workflows via skills and servers) to build an image analysis demo using Angular, the Firebase Hybrid & On-device Inference Web SDK, and Gemini models. Users upload an image and use a Gemini model to analyze it to generate a few alternative texts, tags, recommendations, and CSS tips to enhance the image quality. When the demo is running in Chrome 148+, the Hybrid & On-device SDK leverages the Prompt API of the on-device Gemini Nano model to perform the image-to-text tasks, and the token usage is 0. When other browsers, such as Safari or Firefox, execute the same tasks, the SDK falls back to Cloud AI (Gemini 3.5 Flash model), which consumes tokens. Next, I describe how to install the skills in my Angular project and register the Angular and Stitch MCP servers in the Antigravity CLI to develop the infrastructure, services, and UI design of my demo. 1. Workflow This is my entire workflow from implementing features, generating UI screens, and mapping the screens to Angular components. 2. Skills I installed the grill-with-docs , angular , and firebase skills in my project for the following reasons: grill-with-docs: Conduct a rigid Q&A session to generate a specification for a feature, refactor, or critical fix. AI is responsible for performing thorough analysis, and putting in more efforts to generate code to achieve the task. domain-modeling: The skill is referenced in the SKILL.md of the grill-with-docs skill, so a copy of it is required. code-review: Spawn two sub-agents to review changes to detect code smells and verify that the changes align with the specification. angular: Provide the best practices of modern Angular architecture, such as using signals and signal forms. firebase: Provide the skills for Firebase AI Logic, Firebase Remote, et

2026-07-15 原文 →
AI 资讯

I made an AI yell my workouts at me (Sonic Kinetic)

What I built I wanted a workout timer that doesn't just beep at me. So this weekend I built one that writes the workout AND talks me through it, out loud, in a voice that actually sounds like it's yelling at you when things get hard. You give it a callsign, how long you've got, what you want to work, and how brutal you want it. It hands that to Gemini, which breaks the whole thing into 30-90 second intervals with a coaching line for each one. Then every one of those lines gets turned into real audio by ElevenLabs before it ever hits your browser. Nothing is pre-recorded, nothing is a fixed track. Ask for a different workout, get a completely different script and a completely different set of audio clips, generated on the spot. Demo Unedited screen recording, straight off my machine hitting the real APIs, sound included. Compose a routine, it comes back in a couple seconds, pacing curve draws itself as an SVG line, then hitting Start walks through each interval with the active one highlighted in red as it counts down and you actually hear it. The Maximum-intensity segments sound noticeably more unhinged because I turn the ElevenLabs stability knob way down for those specifically. Code https://github.com/marwankous/sonic-kinetic How I built it Go backend, one endpoint. It takes your workout params, sends a prompt to gemini-3.1-flash-lite with a JSON schema locked down tight enough that I don't have to think about parsing garbage back out of it, and gets back a full timeline plus a heart-rate pacing curve. The part I actually enjoyed was the audio pipeline. Every coaching line in the timeline gets fired off to ElevenLabs at the same time, one goroutine each behind a sync.WaitGroup , so a routine with a dozen segments doesn't take a dozen times longer than one with a single segment. Whatever comes back gets base64'd straight onto its segment. I also tie the eleven_flash_v2_5 stability setting to the segment's energy level, dropping it to 0.30 for anything marked Maximum

2026-07-11 原文 →
AI 资讯

RxJS in Angular — Chapter 9 | Timing Operators — debounceTime, throttleTime, interval & More

👋 Welcome to Chapter 9! Imagine a user typing in a search box. They type "i", "ip", "iph", "ipho", "iphon", "iphone" — 6 keystrokes in 2 seconds. Do you really want to make 6 API calls ? Of course not! You want to wait until they stop typing and then search once. That's what timing operators solve. They control when and how often values flow through your stream. ⏱️ debounceTime() — Wait for the Silence debounceTime(ms) waits until there's a pause of ms milliseconds, THEN lets the latest value through. Think of it like this: "Ignore everything until they stop for a moment." Like a person who waits for you to finish talking before responding. import { debounceTime } from ' rxjs/operators ' ; // User types fast: 'i' → 'ip' → 'iph' → 'ipho' → 'iphon' → 'iphone' // debounceTime(400) waits 400ms of silence, then sends 'iphone' only searchControl . valueChanges . pipe ( debounceTime ( 400 )) . subscribe ( term => { this . searchProducts ( term ); // Only called ONCE with 'iphone'! }); Timeline: Type 'i' → [400ms timer starts] Type 'ip' → [reset timer] Type 'iph' → [reset timer] Type 'iphone'→ [reset timer] ... 400ms silence ... EMIT: 'iphone' ✅ Real Angular Example — Smart Search Box import { Component , OnInit , OnDestroy } from ' @angular/core ' ; import { FormControl } from ' @angular/forms ' ; import { Observable , Subject } from ' rxjs ' ; import { debounceTime , distinctUntilChanged , switchMap , startWith , takeUntil } from ' rxjs/operators ' ; @ Component ({ selector : ' app-search-box ' , template : ` <div class="search-wrapper"> <input [formControl]="searchControl" placeholder="Search products..." (keyup.escape)="clearSearch()"> <span *ngIf="isLoading" class="spinner">🔄</span> <button *ngIf="searchControl.value" (click)="clearSearch()">✕</button> </div> <div class="results-count" *ngIf="(results$ | async) as results"> Found {{ results.length }} results </div> <div class="results"> <div *ngFor="let item of results$ | async" class="result-item"> <strong>{{ item.nam

2026-07-10 原文 →
AI 资讯

Why My Angular 21 Upgrade Failed 👀

I believe Angular upgrades have become much smoother these days. Most of the time, a simple ng update is enough to move to the latest version. Instead, I spent hours chasing errors that looked completely unrelated to the real problem 😭 After upgrading the project to Angular 21, I started seeing errors like these: Cannot find module '@angular/material/chips' Cannot find module '@angular/material/dialog' Then another one appeared: Error: The current version of "@angular/build" supports Angular ^19... but detected Angular version 21.x instead. At first, it looked like Angular Material wasn't installed correctly but i think the actual issue was a version mismatch inside the project. Some packages had already been upgraded to Angular 21: @angular/core @angular/common @angular/material But the build system was still using: @angular-devkit/build-angular@19 Since Angular's build tools are tightly coupled with the framework version, the compiler started producing misleading errors. The build pipeline was the problem. The Commands That Helped I used these commands: npm ls @angular-devkit/build-angular npm explain @angular-devkit/build-angular They showed that my project was still resolving Angular 19's build package. That was the clue I needed and than I verified that every Angular package was using the same major version. Then I cleaned the project completely: rm -rf node_modules rm package-lock.json npm cache clean --force npm install It takes time usually.(and I did it several times cause Im failed 😃) Finally, I confirmed that all Angular packages were aligned before building again.

2026-07-09 原文 →
AI 资讯

Why I Stopped Writing tap() Inside rxResource Streams

There's a pattern I see a lot in Angular codebases that adopted Signals early: a developer discovers rxResource , loves that it handles loading and error state automatically, and then immediately reaches for tap() to write a signal inside the stream. private readonly resource = rxResource ({ params : () => this . paramsSignal (), stream : ({ params }) => this . api . fetch ( params ). pipe ( tap ( data => this . sideSignal . set ( data . meta )) // 💥 ) }); This looks harmless. It runs in development without complaint in zone-based Angular. Then you enable zoneless — or Angular tightens its reactive graph enforcement — and you get NG0600: Writing to signals is not allowed in a reactive context . The rxResource stream runs inside Angular's reactive scheduler. Signal writes there aren't just discouraged — they're illegal by design. The scheduler assumes computed signals and reactive contexts are read-only during evaluation. A write mid-computation breaks the glitch-free guarantee Angular's signal graph is built on. The fix I landed on: make the stream return everything it needs to return, as a single typed value. interface ResourceValue { readonly sections : Section []; readonly meta : Meta ; } private readonly resource = rxResource < ResourceValue , Params > ({ stream : ({ params }) => this . api . fetch ( params ). pipe ( map ( data => ({ sections : transform ( data ), meta : data . meta })) ) }); No tap . No side signal. Everything the rest of the store needs lives in resource.value() and can be read via computed . The lesson isn't "don't use tap". The lesson is that rxResource has a contract: it is a read primitive . Its stream is for fetching and transforming. If you're writing signals inside it, you're treating it as a command bus — and that's a different tool. Originally published on ysndmr.com .

2026-07-08 原文 →
AI 资讯

What We Learned Rewriting an Interactive Map Editor: Fabric.js, CORS, and 20,000 Lines of Legacy TypeScript

A story about how migrating an interactive office map editor turned into an engineering investigation involving Fabric.js, tainted canvas , and an architecture that's finally easy to extend. In most software projects, one sentence usually makes every developer nervous: "Let's rewrite this module from scratch." It often means months of development, regression risks, and endless architecture discussions. Our project was no different. We develop, a workspace management platform that allows companies to manage office spaces and book desks. One of its core features is an interactive office map editor, where administrators upload floor plans, place desks and meeting rooms, and publish maps for employees. Over the years, this editor slowly evolved into a real monolith. And the problem wasn't simply the number of lines of code. Where It All Started The editor dated back to the AngularJS era. The main component had gradually grown into a single file responsible for almost everything: loading maps working with Fabric.js CRUD operations keyboard shortcuts dialogs saving event handling The main editor component alone contained nearly 2,270 lines of code . Behind it lived another codebase — the map engine itself. Almost 20,000 lines of TypeScript spread across more than 230 files. One of the biggest architectural issues was an infinite rendering loop. fabric . util . requestAnimFrame (() => this . tick ()); Even when the user wasn't interacting with the editor, rendering continued forever. It worked. But every new feature became more expensive to build. Why We Decided to Rewrite It The motivation wasn't AngularJS itself. The real reason was business requirements. The product needed completely new capabilities: map drafts safe publishing high-quality printing multiple workspace modes easier support for new object types Every new feature pushed harder against the existing architecture. Eventually it became obvious: We weren't fighting individual bugs anymore. We were fighting the

2026-07-08 原文 →
AI 资讯

Signal Forms vs. Reactive Forms: When Should You Upgrade Your Forms? (Angular 22 Guide)

TL;DR — Angular 22 promoted Signal Forms from experimental to stable. This is not "Reactive Forms are dead." It's a real architectural trade-off, and this post walks through both APIs in full, with production-realistic code, so you can decide feature-by-feature instead of framework-war-by-framework-war. Table of Contents Why This Matters Now The Core Question Reactive Forms: Why It Became the Standard Full Example: Reactive Forms Login Where Reactive Forms Still Excel Signal Forms: What Actually Changed in Angular 22 Full Example: Signal Forms Login Where Signal Forms Shine Side-by-Side: Core Concepts Mapped Deep Dive: Validation Synchronous Validation Cross-Field Validation Conditional Validation with when() Async Validation Deep Dive: Dynamic and Nested Forms Nested Form Groups Dynamic Collections (FormArray-style) Deep Dive: Form State — Dirty, Touched, Errors, Submission Developer Experience and Testing Performance Considerations Interop: Migrating Without a Big-Bang Rewrite Migration Strategy for Enterprise Teams When NOT to Migrate Decision Framework FAQ Closing Thoughts Why This Matters Now With Angular 22 (released June 3, 2026), Signal Forms left experimental status and became part of the stable, supported API — alongside resource() and httpResource() . That's a meaningful milestone: it means the Angular team ran extensive internal case studies across real form-heavy applications at Google before committing to stability, and the interop story with Reactive Forms has matured enough that a big-bang rewrite is no longer the only migration path. At the same time, Angular 22 also flips two important defaults: components now use OnPush change detection by default, and zoneless change detection continues its push toward becoming the standard. Signal Forms is part of that same story — Angular's reactivity model finally speaking one dialect end-to-end, from component state to form state to async data. None of this makes Reactive Forms obsolete. It changes what "the

2026-07-07 原文 →
AI 资讯

From Angular.js to Fine-Grained Reactivity: Part 2 — The JS Proxy Runtime

In the first article of this series, we saw how a custom build-time compiler can transform a legacy Angular.js template into raw, optimized JavaScript. To recap, starting from this template: <!-- simple.html --> <p> Hello {{ name }}! </p> Our Go compiler generates the following JavaScript module: // simple.js export function template () { const p_0 = document . createElement ( " p " ); const text_1 = document . createTextNode ( "" ); p_0 . append ( text_1 ); return { mount ( container ) { container . append ( p_0 ); }, update ( change ) { if ( " name " in change ) { text_1 . data = " Hello " + change . name + " ! " ; } } } } This is incredibly clean. By running template() , we get an object with mount and update methods. Using mount is fully intuitive: we pass a reference to a DOM element, and it injects our empty paragraph ( p_0 ) into it: import { template } from ' ./simple.js ' ; const { mount , update } = template (); const container = document . getElementById ( ' view-container ' ); mount ( container ); // The DOM now contains: <p></p> (waiting for data) However, the paragraph remains empty until we call update with a change object like this: let changes = { name : " Mario " , }; update ( changes ); // The DOM surgically updates to: <p>Hello Mario!</p> But who is responsible for tracking changes in our application state, building this changes object, and calling update ? The answer lies in marrying the legacy Angular.js $scope with the modern JavaScript Proxy API . The Legacy State Pattern In a traditional Angular.js application, developers mutate the state directly inside a controller by assigning properties to the $scope object: // simple-controller.js export function SimpleController ( $scope ) { $scope . name = " Mario " ; } To bridge the gap between this legacy controller and our new build-time template, we need a way to automatically capture the assignment $scope.name = "Mario" and translate it into a structured update: let changes = { name : " Mario " }

2026-07-06 原文 →
AI 资讯

Ng-News 26/16: OpenNG Foundation, spartan/ui

OpenNG Foundation and spartan/ui 1.0 are the headline topics this week: a new home for libraries like Spectator and Elf, and spartan/ui, a stable shadcn-inspired component library for Angular. Also in brief: Storybook's Angular modernization through AnalogJS, the end of ng-conf, and AI Dev Craft in Las Vegas. OpenNG Foundation Maintaining open-source libraries is hard work. Developers often do it in their spare time, committing to years of maintenance, adding new features, and responding to user requests. Last episode, we reported that the ngneat organization was taken down for unknown reasons. While we still don't know why it happened, a new home has emerged for its popular libraries like Spectator and Elf: the OpenNG Foundation. Gerome Grignon, known for CanIUseAngular and as the organizer of Ng-Baguette, announced the foundation, which is already hosting these libraries. Alongside Gerome, the current OpenNG team also includes Dominic Bachmann, organizer of Angular Lucerne and author of the angular-typed-router library. OpenNG Foundation · GitHub OpenNG Foundation has 8 repositories available. Follow their code on GitHub. github.com spartan/ui 1.0 spartan/ui has officially released its 1.0 version. It provides an "accessible, production-ready library of more than 55 components" with fully customizable styling. After debuting in August 2023 with 30 primitives, it now reaches stable in 2026 with a modern architecture built around signals, standalone components, zoneless change detection, and SSR. Originally initiated by Robin Götz, a full team quickly formed around the project. spartan/ui can be seen as the Angular equivalent to shadcn/ui, famous for its customizability. While similar open-source alternatives exist, spartan/ui was the pioneer and has a proven track record of active maintenance over the years. Announcing spartan/ui 1.0 Robin Goetz Robin Goetz Robin Goetz Follow for Playful Programming Angular Jun 24 Announcing spartan/ui 1.0 # angular # webdev 8 reac

2026-07-03 原文 →
AI 资讯

🚦Modern Angular Guards: Architecture, Best Practices & Enterprise Patterns

Modern Angular Guards: Architecture, Best Practices & Enterprise Patterns A deep dive into designing lightweight, composable, and maintainable routing guards in modern Angular applications. Table of Contents Introduction Why Guards Exist The Golden Rule of Angular Guards Functional Guards: The Modern Standard CanActivateFn: Authentication Guard CanMatchFn: Permission-Based Route Matching CanDeactivateFn: Unsaved Changes Guard CanActivateChildFn: Nested Route Protection Signals + Guards: Reactive Permission State Feature Flags in Routing Guard Composition Patterns UrlTree Redirects vs Imperative Navigation Async Guards: When and How Permission Service Architecture Role-Based Access Control (RBAC) Permission-Based Access Control (PBAC) Route Data for Configuration Lazy Loading with Guards Standalone Routing with provideRouter Route-Level Providers Guards vs Interceptors Guards vs Backend Authorization Performance Considerations Navigation UX Best Practices Error Handling in Guards Testing Guards Common Mistakes Production Checklist Enterprise Routing Insights Conclusion Introduction In modern Angular applications, routing guards have evolved from class-based monoliths into lightweight, composable functions. This shift isn't just syntactic—it's architectural. As Angular applications become larger and more complex, the routing layer becomes a critical piece of the architecture. Guards are the gatekeepers of your navigation, but they should never become the orchestrators of your application logic. This article is for senior Angular developers, software architects, and team leads who are designing routing strategies for enterprise-scale applications. We won't explain what a route guard is—we'll explore how to architect them properly. Why Guards Exist Guards exist to protect navigation boundaries. They evaluate whether a transition should proceed, redirect, or be blocked. In modern Angular, this is achieved through functional guards that return: boolean — allow or block na

2026-07-01 原文 →
AI 资讯

How to Stop AI Agents from Writing Legacy Angular Code (The Angular 22 Guardrail)

Every developer using Cursor , Claude Code , Windsurf , or GitHub Copilot knows this exact frustration: You are building a cutting-edge Angular 22 application. You ask your AI coding assistant to spin up a dynamic form, a lazy-loaded list, or an asynchronous data card. Instead of leveraging modern fine-grained reactive Signals, optimized native block control flows, or proper SSR hydration hooks, the AI drops an unoptimized pile of legacy tech debt full of NgModules , *ngIf , *ngFor , and raw RxJS BehaviorSubjects . The LLM Training Paradox Why does this happen? Large Language Models are trained on historical code datasets. Statistically, more than 90% of the public Angular repositories and StackOverflow threads on the internet represent older paradigms. Left to their own devices, agents default to the statistical average of their training data. They literally default to the past. The Fix: angular22-agent-skills To solve this, I built a public, open-source repository of custom instruction bundles and system guardrails leveraging the new skills.sh tool standard. By injecting this verified context directly into your development environment, you force your local AI agents to bypass their training averages and write pristine, optimized, modern Angular 22 syntax every single time. 👉 Check out the repo here: https://github.com/PavanAnguluri/angular22-agent-skills 🔍 The Difference: Before vs. After To understand why these guardrails are necessary, look at what an AI agent writes out of the box versus what it writes once you apply the angular22-agent-skills harness. 🚫 What AI Agents Generate by Default (Legacy) // The AI falls back to old decorators and heavy RxJS boilerplate for standard state import { Component , Input , OnInit } from ' @angular/core ' ; import { BehaviorSubject } from ' rxjs ' ; @ Component ({ selector : ' app-user-profile ' , template : ` <div *ngIf="visible"> <h3>{{ firstName }} {{ lastName }}</h3> <div *ngFor="let item of items"> {{ item.name }} </div>

2026-06-24 原文 →
AI 资讯

Announcing spartan/ui 1.0

After a long and deliberate alpha, spartan/ui is now 1.0 . We shipped the first 30 primitives in August 2023 with a simple bet: building accessible, good-looking UI in Angular is harder than it should be, and the community deserved a better starting point. Almost three years later, that bet has grown into a stable, production-ready library of more than 55 components - built on signals, ready for zoneless, and server-side-rendering compatible out of the box. Here's what 1.0 actually means. Stable, and ready to build on We stayed in alpha for a long time on purpose. It let us refine the APIs in the open, with real applications putting real pressure on the design, instead of freezing a v1 we'd regret six months later. That patience is what 1.0 cashes in. The APIs are now stable and semantically versioned, so you can depend on spartan/ui/brain and upgrade with confidence. The copy-in spartan/ui/helm layer stays exactly as it's always been - yours to own, read, and customize. No black boxes, no fighting the library to change a style. Built for modern Angular Every primitive is built on Angular signals and standalone components. spartan is zoneless-ready and SSR compatible out of the box, so it drops cleanly into how Angular apps are actually written today - no extra setup, no adapters. The split that's defined spartan from day one still holds. spartan/ui/brain carries the hard, unglamorous parts - ARIA, keyboard navigation, focus management - and keeps them maintained so you don't have to. spartan/ui/helm gives you full styling control on top, copied into your project like a recipe. Accessibility you can rely on; appearance you fully own. From 30 primitives to 55+ The alpha shipped with 30 components. 1.0 ships with more than 55 - nearly double - including many of the most-requested additions over the past two years: Data Table - sorting, filtering, and selection, the piece people asked for most Sidebar - composable app navigation Calendar and Date Picker Carousel , Auto

2026-06-24 原文 →
AI 资讯

Angular Material Theming System Course — Now 100% Free

If you've worked with Angular Material, you know theming can be one of the trickiest parts of the library — especially after the move to Material 3. Token-based theming, custom palettes, dark mode, component-level overrides... there's a lot going on under the hood. I built a full course to break it all down, and I'm excited to announce it's now completely free . What's in the course Angular Material Theming System is a deep, practical walkthrough of Angular Material's theming API for Material 3. By the end, you'll be able to: Build and customize themes from scratch Apply themes at the application level Override and extend themes for individual components Work confidently with Angular Material's theming tokens and APIs It's 46 lessons and roughly 4.5 hours of content, all hands-on and example-driven. Where to find it 🎥 Watch on YouTube: https://www.youtube.com/playlist?list=PLOjtJUnDeEIyaeUs_jrxylnD2IxSb3Ku7 📝 Read the article version: https://angular-ui.com/courses/angular-material-theming/ 💻 Full source code on GitHub: https://github.com/Angular-UI-com/angular-material-theming If you're building with Angular Material and theming has ever felt like a black box, give it a watch. I'd love to hear your feedback in the comments. If this helped you, consider checking out Angular Material Blocks — a library of pre-built Angular Material + Tailwind components, available via a simple CLI.

2026-06-21 原文 →
AI 资讯

Building Real-Time Dashboards in Angular with WebSockets — A Complete Guide

Most dashboards are built the same way: the user lands on the page, data loads, and then... it sits there. Stale. Until the user hits refresh or you set up an awkward polling interval that hammers your server every few seconds. There's a better way. WebSockets give you a persistent, two-way connection between your Angular app and your server — meaning your dashboard updates the moment new data exists, with zero wasted requests. In this article we'll build a complete real-time dashboard in Angular from scratch — WebSocket service, Signal-based components, auto-reconnection, and production-ready patterns. How WebSockets Differ From Regular HTTP Before writing any code, it's worth understanding what makes WebSockets special. Regular HTTP: Client → "Give me data" → Server Client ← "Here's your data" ← Server [Connection closes] WebSocket: Client ←→ Server [Connection stays open] Server → "New data!" → Client (anytime) Server → "More data!" → Client (anytime) Client → "Send this" → Server (anytime For a real-time dashboard showing live metrics, user activity, or financial data — the WebSocket model is a natural fit. The server pushes updates the moment they happen. No polling, no refresh button, no stale data. Project Setup For this article we'll build a dashboard that shows three live metrics: active users, requests per second, and server CPU usage. Start with a fresh Angular 22 project: ng new realtime-dashboard --standalone cd realtime-dashboard ng serve RxJS ships with Angular so no extra dependencies are needed — webSocket from rxjs/webSocket handles everything. Step 1 — Define Your Data Model Start with a clear TypeScript interface for the data your server will push: // core/models/dashboard.model.ts export interface DashboardMetrics { activeUsers : number ; requestsPerSecond : number ; cpuUsage : number ; timestamp : Date ; } export interface MetricAlert { type : ' warning ' | ' critical ' ; metric : string ; value : number ; message : string ; } export type Dashb

2026-06-21 原文 →
AI 资讯

Ngrx Signal Store

In recent years, Angular has taken an important step toward a simpler and more declarative reactivity model with the introduction of Signals . NgRx, which has long been the de facto standard for state management in complex Angular applications, followed this evolution by introducing Signal Store . The goal is not to completely replace @ngrx/store , but to offer a lighter and more local alternative, designed for use cases where the classic Actions → Reducers → Selectors pattern feels excessive. In this article, we'll see how to use NgRx Signal Store to build a reactive, typed store that integrates seamlessly with Angular components, drastically reducing boilerplate and improving code readability. This tutorial is aimed at Angular developers who are already familiar with Signals and "classic" NgRx. What is NgRx Signal Store NgRx Signal Store introduces a different way of thinking about state compared to classic @ngrx/store . A Signal Store : is not based on Redux does not use actions or reducers does not require explicit selectors Instead, the model revolves around three main concepts: 🧩 State State is defined as a set of signals , typically using withState . Each state property is immediately reactive and can be read directly by components. 🧠 Derived state Derived state is defined using withComputed . It is the conceptual equivalent of selectors, but with a more direct syntax and better integration with Angular's Signals system. 🔧 Methods State changes and side effects (such as HTTP calls) are encapsulated in methods declared with withMethods . This keeps the store logic in a single place, without having to orchestrate multiple files as in the traditional NgRx pattern. In other words, a Signal Store resembles a strongly structured reactive service more than a pure Redux store. This approach makes Signal Stores particularly suitable for: local or feature state small to medium-sized applications reducing complexity in contexts where Redux would be overkill Creating the

2026-06-17 原文 →
AI 资讯

Angular's Official Agent Skills Helps AI Coding Tools Write Modern Angular

Google's Angular team has released a repository called angular/skills, focusing on Agent Skills that enhance AI coding agents' ability to write modern Angular code. The repository includes skills for generating code and scaffolding applications, reinforcing current Angular conventions. It serves as a snapshot, aiming to improve AI suggestions by providing updated context. By Daniel Curtis

2026-06-12 原文 →
AI 资讯

Web MCP: give some tools to your agent

Introduction Nowadays, AI agents are becoming increasingly powerful at assisting users in their daily web activities. However, we cannot yet allow them to act completely autonomously—there is still a risk of them clicking on the wrong elements, for instance. In theory, these agents are capable of performing impressive tasks, provided they are guided step-by-step through the interface. The challenge here is not a lack of intelligence in the model, nor a shortage of web APIs to expose data to the agent. The core issue lies in the fact that the agent must currently "guess" its way through applications that were designed exclusively for humans. This is precisely the problem that WebMCP is here to solve. It is important to note that these are not intended to replace standard APIs as access points for an application. Instead, they provide a structured way for a web application to "instruct" the AI agent used in the browser on how to navigate its interface. This results in: Fewer misplaced clicks. Less trial-and-error when interacting with the UI. When utilized to their full potential, WebMCPs could redefine the user experience in the coming years. What is WEBMCP? As you may have guessed, WebMCP is a browser-side "guide/standard" for exposing tools to an AI agent directly from an active web page. During Google I/O, this new feature was introduced as a way for web applications to describe how a page functions—and what actions can be performed—to various AI agents. As a result, agents can execute these described actions faster, more efficiently, and with greater precision. Unsurprisingly, the syntax for creating these descriptions relies on JavaScript functions. These functions take natural language descriptions as parameters, along with structured schemas directly exposed from the web page. This is exactly where the power of WebMCP lies. Today, while we have Playwright (designed for end-to-end testing of web applications) and Playwright MCP (which extends this model to LLMs

2026-06-11 原文 →
AI 资讯

I built a Spring Boot + Angular + JWT Full Stack Starter Kit — here's what I learned

Why I built this Every time I started a new Java full stack project I was spending 2-3 days just on setup — JWT configuration, Spring Security, CORS, connecting Angular to backend. So I decided to build a reusable starter kit once and never do that setup again. What I built A complete full stack starter kit with: Spring Boot 3.5 REST API Angular 19 frontend connected to backend MySQL database with User table ready JWT Authentication working out of the box Spring Security configured Full CRUD operations Clean layered architecture (Controller → Service → Repository) The Tech Stack Backend: Java 17, Spring Boot, Spring Security, JWT, JPA Frontend: Angular 19, TypeScript Database: MySQL How it works User registers via POST /api/users User logs in via POST /api/auth/login Backend returns JWT token Frontend stores token in localStorage All protected routes require valid token Invalid or missing token returns 401 Unauthorized What I learned JWT configuration in Spring Security is confusing at first CORS needs to be configured in SecurityConfig not just main class Angular HttpClient needs provideHttpClient() in app.config.ts Service layer keeps code clean and testable GitHub Full source code is available here: https://github.com/shindebuilds/springboot-angular-starter-kit Feel free to clone it, use it, improve it. If you want the packaged version with setup instructions: https://hanumant4.gumroad.com/l/caopgu Happy building!

2026-06-10 原文 →
AI 资讯

A 13 KB text file beat a smarter model: benchmarking AI codegen across 5 Angular state libraries

Disclosure up front: I maintain one of the five libraries tested (SignalTree), and it's the one that scored worst in the cold run — so this isn't a "look how good my thing is" post. The cross-library pattern and the fix were interesting enough that I wanted to put the numbers in front of people who use Copilot/Cursor/Claude Code every day. The whole harness is reproducible (one command, link at the bottom); I'd rather it get torn apart than taken on faith. Setup Libraries : NgRx (classic), NgRx SignalStore, Akita, Elf, SignalTree. Agents : Claude Sonnet 4.6, GPT-5.4, Gemini 3.1 Pro, Perplexity Sonar Pro, Claude Haiku 4.5, GPT-5.4-mini. 8 prompts : counter, paginated users, debounced search, derived totals, login form, undo/redo, deep nested state, multi-marker editor. 5 libs × 6 agents × 3 priming modes = 720 cells . Temperature 0. Identical prompt text per library (only the library name swapped). Scored on three orthogonal checks: idiomatic-pattern match, import resolution (does every import resolve to a real package), and method validity (do the called methods actually exist on the API). What this measures: one-shot generation. The agent gets the prompt, returns a file, we score it. Real interactive use — Cursor/Copilot with chat back-and-forth, where the model sees its own errors and gets a second try — is a different setting, and the lift could be larger or smaller there. This is the cold-shot case. Finding 1: cold accuracy basically tracks how much the library is in the training data No context provided, just "write this in library X": Library Cold score Akita 94% Elf 94% NgRx (classic) 91% NgRx SignalStore 86% SignalTree 49% The libraries that have been around for years, with thousands of blog posts and Stack Overflow answers, score in the 90s. The youngest/smallest library in the set scores ~49%. That gap isn't really a quality signal — it's a corpus signal. The models have simply seen orders of magnitude more Akita than SignalTree. Worth keeping in mind any

2026-05-30 原文 →