THẢO LUẬN

@thienhavodinh cảm ơn bạn, mình đã có cái nhìn sâu hơn về chủ đề này 👍

0

@nguyen.thanh.minhb Cái này là mình đọc từ code ra. Có vẻ như tác giả để như vậy để dễ hình dung cho người mới nhưng như thế thì mình nghĩ là nên note lại.

Screen Shot 2020-10-01 at 10.07.48.png

Trong Flutter thì mình hiểu có 2 loại Element chính là ComponentElementRenderObjectElement. RenderObjectElement thì cung cấp RenderObject còn ComponentElement thì gián tiếp cung cấp RenderObject thông qua việc giúp định nghĩa nên cấu trúc của ElementTree. ComponentElement bao gồm 3 elements nhỏ hơn là StatelessElement (Chả làm gì ngoài việc gọi hàm build của widget), StatefulElement (Làm nhiều hơn một tí bằng cách quản lý vòng đời của State), và ProxyElement (Cung cấp ProxyWidget là widget mặc định có 1 final child và không có hàm build())

+2

cám ơn bạn đã chia sẻ,

đúng là để an toàn nhất thì nên dùng 1 user độc lập thay vì tận dụng user node vì có thể user node mà người ta tạo sẵn họ còn cho thêm nhiều quyền khác nữa (ví dụ có quyền sudo chẳng hạn)

tạo 1 user mới, độc lập, chỉ có vừa đủ quyền chạy app của chúng ta là được

0
thg 9 30, 2020 4:02 CH

chào bạn mình đã check lại,

khả năng là bạn đã quên đoạn Note mình nói ở phần setup authentication cho MongoDB, đó là cần clear DB cũ (DB lúc chưa có authentication), vì nếu không thì khi chạy lên phần authentication sẽ không nhận vì tên database của ta trùng nhau, Mongo thấy DB cũ vẫn có nên sẽ không làm gì cả.

Mình vừa update cách xóa volume cho MongoDB trên Windows, bạn check lại phần authentication cho Mongo trong bài nhé.

Mình đã test lại trên Win 10 và chạy ngon

0

cảm ơn bạn đã ủng hộ, mình sẽ cố gắng ra bài mới sớm 😄

0
Avatar
đã bình luận câu trả lời trong câu hỏi
thg 9 30, 2020 2:54 CH

@subhopefully có framework mà dùng là ngon rồi bạn.
Trước mình từng làm CI2, symfony 1.4 doc tìm còn khó, cơ mà vẫn học đc rất nhiều thứ 😄
cho dự án php7.4.9 lastest version mà bạn phải code thuần thì còn khổ hơn.

+1

đúng rồi bạn. trang nào phải có cơ sở và thông tin thì nó mới detect đc chứ. còn mình mà cố tình dấu đi thì tool cũng bó tay thôi

0

@thienhavodinh Hình đó mình lấy từ nguồn này, tác giả thuộc Flutter team nên cũng là một nguồn đáng tin chứ nhỉ. Hy vọng bác cho ý kiến để mọi người cùng học hỏi. https://medium.com/flutter/how-to-create-stateless-widgets-6f33931d859

create element.PNG

0

@manh11235 Wow, lần vào Container thì đúng như bạn nói, nó tạo RenderObject nhờ tạo thằng ColoredBox là một RenderObjectElement trong hàm build. Thảo nào, doc nó nói ComponentElement tạo gián tiếp RenderObject thông qua thằng Element khác, thằng ColoredBox là thằng gọi hàm createRenderObject, ko phải thằng Container Element gọi. 👍

0

@nguyen.thanh.minhb mình cũng từng đọc qua https://medium.com/flutter-community/flutter-what-are-widgets-renderobjects-and-elements-630a57d05208 , nhưng vì k hiểu được rõ ràng có lẽ do trình tiếng anh toàn phải google nên mình chủ yếu lần theo các class đi theo nó (commander + B ). ví dụ : Container -> StatelessWidget -> tạo ra StatelessElement , kế thừa từ ComponentElement -> Vào ComponentElement thì hàm mount không gọi widget.createRenderObject. Ngược lại: Column -> Flex, kế thừa từ MultiChildRenderObjectWidget -> taọ ra MultiChildRenderObjectElement , kế thừa từ RenderObjectElement. hàm mount gọi widget.createRenderObject.

Nhưng ComponentElement không gọi widget.createRenderObject thì để tạo nên RenderObject tree thì làm thế nào. Cái này lần theo hàm build của Container. Nó trả về ví dụ như ColoredBox -> kế thừa từ RenderObjectWidget-> tạo ra RenderObjectElement . Suy ra ComponentElement cũng được tạo ra từ RenderObjectElement

+2

Hình đó mình lấy từ nguồn này, tác giả thuộc Flutter team. https://medium.com/flutter/how-to-create-stateless-widgets-6f33931d859

create element.PNG

Còn 2 loại Element thì đúng như bạn nói, một thằng tạo trực tiếp, một thằng tạo gián tiếp. Để mình update. Cảm ơn bạn nhé 👍

/// Rather than creating a [RenderObject] directly, a [ComponentElement] creates
/// [RenderObject]s indirectly by creating other [Element]s.
0

Bạn có nguồn nào nói về cái này không. Mình tìm hiểu từ sách, nó không nói kĩ đến mức này. Cảm ơn bạn

0

Mấy chỗ như DecoratedBox, Padding, Column bị lộn thì phải. 3 widget này kế thừa từ RenderObjectWidget, RenderObjectWidget tạo ra RenderObjectElement. Còn StatelessElement , StatefulElement hay InheritedElement là ComponentElement. Có thể chia thành 2 loại element chính là 1.ComponentElement ( StatelessElement , StatefulElement hay InheritedElement ). Loại này không tạo RenderObject 2.RenderObjectElement (Center, Padding,...).Loại này mới tạo RenderObject bằng cách gọi widget.createRenderObject trong hàm mount

+2

Sự khác nhau giữa so sánh == và identical

void main() {
  final userA = User(1, 'Minh');
  final userB = User(1, 'Minh');

  // Toán tử == sẽ so sánh giá trị
  print(userA == userB); // true vì cả userA và userB đều có id là 1 và name là Minh

  // hàm identical sẽ kiểm tra xem userA với userB có cùng trỏ đến 1 object không
  print(identical(userA, userB)); // false vì userA và userB không cùng trỏ đến 1 object

  final userC = userA; // userC trỏ đến cùng object với userA
  print(identical(userA, userC)); // nên hàm identical print ra true
}

class User {
  User(this.id, this.name);

  final int id;
  final String name;
  
  // ta sẽ override lại toán tử ==
  // tức là ta định nghĩa lại "Khi nào thì 2 User gọi là == nhau)
  
  bool operator ==(Object other) {
    // Khi 2 user có cùng id và cùng name thì chúng bằng nhau
    return id == (other as User).id && name == (other as User).name;
  }
}
+1
thg 9 30, 2020 10:16 SA

Câu này có bị ngược k tác giả ơi "Để tạo chữ ký, người gửi sẽ dùng private key và người nhận sẽ dùng public key để xác thực chữ ký đó" ?

0

@maitrungduc1410 đã thông não thành công, cảm ơn chia sẻ của a.

+1
thg 9 30, 2020 9:33 SA

Bài viết rất cụ thể. Bạn Anh cho hỏi code viết labelText như thế nào? Trong bài ko thấy. Tks

0

Câu 2: tại sao ngay từ đầu trong cái source này https://dartpad.dev/cbcf93cfd5655c514af90e87010be7c3 , mình sử dụng UniqueKey nhưng State của widget Tile vẫn được giữ như cũ. Bằng chứng là màu sắc của Tile nó nó không bị reset thành 1 màu mới. Còn trong ví dụ lần này thì một State mới của TextField đã được tạo ra.

Trả lời: Đầu tiên first build, thì object _MyHomePageState được khởi tạo lần đầu và biến listTile trong _MyHomePageState cũng được khởi tạo lần đầu. Giả sử lúc khởi tạo lần đầu này object Tile thứ nhất trong listTile có màu đen và key là 1, object Tile thứ 2 có màu đỏ và key là 2. Khi gọi hàm setState, nó chỉ đơn giản là swap 2 object Tile này chứ không tạo ra một object Tile mới thay thế. Hơn nữa _MyHomePageState cũng không có bị destroy nên biến listTile cũng không được tạo mới. Tóm lại, 2 object Tile được tạo từ đầu, không bao giờ bị destroy nên tất nhiên Key nó sẽ không thay đổi. Trước key là 1, sau khi rebuild vẫn là 1, trước là 2 thì sau vẫn là 2, vì vậy Element so sánh thấy Key trước và sau đều không đổi nên State được bảo toàn. Còn trong ví dụ 2 TextField thì khi rebuild 1 object TextField mới được tạo ra, nên trước đó key có thể là 1, sau khi rebuild key có thể là 3. Vì vậy, trước và sau khi rebuild, Element so sánh thấy key khác nhau nên destroy chính nó, tạo ra Element mới và State mới.

class MyHomePage extends StatefulWidget {
  
  _MyHomePageState createState() {
    return _MyHomePageState();
  }
}

class _MyHomePageState extends State<MyHomePage> {
  var listTile = <Widget>[Tile(key: UniqueKey()), Tile(key: UniqueKey())];

  
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Row(
          children: listTile, 
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: swapTwoTileWidget, 
        child: Icon(Icons.swap_horiz),
      ),
    );
  }

  
  void swapTwoTileWidget() {
    setState(() {
      listTile.insert(1, listTile.removeAt(0));
    });
  }
}

class _TileState extends State<Tile> {
  final Color color = generateRandomColor();
  
  Widget build(BuildContext context) {
    
    return Container(
      color: color,
      width: 100,
      height: 100,
    );
  }
}
0
Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí