Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
137 views
in Technique[技术] by (71.8m points)

html - Why can't I style my first word within my Angular ngFor loop?

I'm currently trying to style the first word of a string inside my Angular ngFor loop. Somehow the class get's applied but not the style inside my CSS file. Also inline styling don't works - why?

This is my CSS I want to apply:

#page-image-title-table .first-entry-word {
  font-weight: 500;
}

This is my function to wrap my first word into an element with my class above:

formatTableEntry(tableEntry: string): string {
  const tableEntryParts = tableEntry.split(' ');
  const firstWord       = tableEntryParts[0];

  tableEntryParts.shift();

  const restOfString = tableEntryParts.join(' ');

  return `<span class="first-entry-word">${firstWord}</span> ${restOfString}`;
}

And this is my HTML with my loop:

<div id="page-image-title-table">
  <div class="page-image-title-table-row" *ngFor="let tableEntry of tableEntries">
    <span [innerHTML]="formatTableEntry(tableEntry)"></span>
  </div>
</div>

You can see my working example here:

https://angular-ivy-g7ov5s.stackblitz.io


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I see multiple issues here.

  1. Binding a function to directive [innerHTML]="formatTableEntry(tableEntry)" will lead to performance issues in default change detection strategy.

  2. Using innerHTML binding like you're attempting is not elegant in Angular.

  3. font-weight: 500 is the default weight value. Bold is equal to 700.

  4. Perhaps unimportant to the actual issue, but the Stackblitz doesn't seem to work for me in FF and Chrome.

Solution

You could whip up a quick pipe to split the sentences to the required format.

split.pipe.ts

@Pipe({
  name: 'split', 
  pure: true
})
export class SplitPipe implements PipeTransform {
  transform(value: any, args?: any): any {
    if (!value) {
      return null;
    }

    return value.reduce((acc, curr) => {
      const [first, ...rest] = curr.split(" ");
      acc.push({ first: first, rest: rest.join(" ") });
      return acc;
    }, []);
  }
}

It could then be use in conjunction with *ngFor directive akin to keyvalue pipe.

Try the following

app.component.ts

@Component({
  selector: "my-app",
  template: `
    <div id="page-image-title-table">
      <div 
        class="page-image-title-table-row" 
        *ngFor="let tableEntry of (tableEntries | split)"
      >
        <span>
          <span class="first-entry-word">{{ tableEntry.first }}</span>
          {{ tableEntry.rest }}
        </span>
      </div>
    </div>
  `,
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  tableEntries = [
    "First element of the array",
    "Second sample element of the array",
    "lorem ipsum dolor sit amet",
    "Quick brown fox jumps over the lazy dog"
  ];
}

app.component.css

#page-image-title-table .first-entry-word {
  font-weight: 700;
}

Working example: Stackblitz


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...